Preview environments using GitHub Actions
This guide configures GitHub Actions to deploy a Preview Environment for every pull request, run your automated tests against it, and destroy it when the pull request closes.
Prerequisites
- An Okteto account
- A GitHub account
This guide uses the Movies app from the getting started guide. Fork the repository to your GitHub account so you can configure secrets and open pull requests. If you're using your own application, make sure your Okteto Manifest defines the deploy and test sections.
Step 1: Create the GitHub Workflow
A Preview Environment follows the lifecycle of a pull request. Whenever a pull request is opened or updated, the workflow deploys a Preview Environment in Okteto with the code in the pull request, and comments the Preview Environment URL on the pull request.
Create a .github/workflows folder in the root of your repository and save the following workflow file in it. The sample repository already includes the final version of this workflow, with the test steps you add in Step 4.
# file: .github/workflows/preview.yaml
on:
pull_request:
branches:
- main
concurrency:
# more info here: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
jobs:
preview:
runs-on: ubuntu-latest
steps:
- name: Context
uses: okteto/context@latest
with:
url: ${{ secrets.OKTETO_CONTEXT }}
token: ${{ secrets.OKTETO_TOKEN }}
- name: Deploy preview environment
uses: okteto/deploy-preview@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: pr-${{ github.event.number }}
timeout: 15m
What each step does:
okteto/contextconnects the workflow to your Okteto instance.okteto/deploy-previewdeploys the Preview Environmentpr-<number>with thedeploysection of your Okteto Manifest, and comments its URL on the pull request.
Important: Always set cancel-in-progress: false for preview environment workflows.
Setting to true will cancel in-progress deployments, which can lead to:
- Incomplete deployments leaving your preview environment in an inconsistent state
- Resource leaks in your Okteto cluster
- Failed cleanup operations
Recommended approach:
- For preview deployments: Set
cancel-in-progress: false(as shown above) - To manage queued workflows: Use GitHub's UI to manually cancel queued (not in-progress) workflows, or configure your CI/CD pipeline to handle this at the queue level rather than during execution
The concurrency group configuration above ensures that workflows are properly queued per pull request, preventing concurrent deployments to the same preview environment.
Step 2: Configure your secrets
The workflow reads your Okteto credentials from the secrets.OKTETO_TOKEN and secrets.OKTETO_CONTEXT secrets, so you don't commit them to your repository.
Create the following secrets in your repository:
OKTETO_TOKENwith an Okteto Admin Access TokenOKTETO_CONTEXTwith the URL of your Okteto instance (e.g.https://okteto.example.com).
See Using secrets in GitHub Actions for adding these to your GitHub repository.
The workflow also uses secrets.GITHUB_TOKEN, which GitHub populates automatically.
Step 3: Open a Pull Request and see your changes live
Make a change in a new branch of your repository and open a pull request against main. GitHub receives the event and starts your workflow. You can see the workflow's status and logs in the Checks section of the pull request.

When the deployment finishes, the workflow comments the URL of your Preview Environment on the pull request. Open it to see your changes running, and share it with your team to review them.

Every time the branch is updated, the same workflow runs again and redeploys the Preview Environment.
Step 4: Run your tests on every pull request
The Preview Environment is where your automated tests run on every pull request. The Okteto Manifest of the Movies app defines two Test Containers: frontend runs the frontend unit tests, and e2e runs Playwright end-to-end tests against the deployed application and exports their reports as artifacts:
test:
frontend:
image: node:20
context: frontend
caches:
- yarn/.cache
- node_modules
commands:
- yarn install
- yarn test
e2e:
image: ghcr.io/okteto/playwright:chromium
context: e2e
caches:
- yarn/.cache
- node_modules
commands:
- bash run_tests.sh
artifacts:
- test-results
- playwright-report
Add the following steps at the end of the preview job in your .github/workflows/preview.yaml file:
- name: Checkout code
uses: actions/checkout@v4
- name: Run tests
uses: okteto/test@latest
with:
namespace: pr-${{ github.event.number }}
- name: Save Playwright report
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: e2e/playwright-report/
retention-days: 30
What each step does:
actions/checkoutclones the repository so theokteto/testaction can read your Okteto Manifest and send the testcontextto Okteto.okteto/testruns the Test Containers defined in thetestsection of your Okteto Manifest, in the Namespace of the Preview Environment. Thenamespacevalue must match thenameof theokteto/deploy-previewstep. Use thetestsinput to run only some Test Containers, for exampletests: e2e.actions/upload-artifactattaches the Playwright report exported through theartifactsfield to the workflow run. Theif: ${{ !cancelled() }}condition uploads it even when a test fails, so you can inspect the results of a failed run.
The okteto/test action also accepts the timeout input (default 5m), variables to pass variables to your tests, no-cache to ignore the Test Container caches, and file to set the path of your Okteto Manifest. See the okteto test reference for the behavior of each option.
Every pull request now runs the same Test Containers that developers run with okteto test against their Development Environment. Developers iterate on their tests locally, without pushing changes and waiting for CI, and know that the tests behave exactly the same way when they run in CI.
Step 5: Check your test results
Push the workflow change to the branch of your pull request. The workflow redeploys the Preview Environment and runs your tests against it.
The Run tests step shows the output of each Test Container. When a Test Container fails, the step fails and the check on the pull request shows the failure, so you can block merging until the tests pass.
The Playwright report is available as the playwright-report artifact in the summary of the workflow run, for both passing and failing runs. The Preview Environment keeps running after the tests finish, so your team can still open it to review the changes.
Step 6: Cleanup
The sample repository also includes a workflow to destroy the Preview Environment when the pull request is closed or merged. Add it to your repository to remove Preview Environments automatically:
# file: .github/workflows/preview-closed.yaml
on:
pull_request:
types:
- closed
jobs:
closed:
runs-on: ubuntu-latest
steps:
- name: Context
uses: okteto/context@latest
with:
url: ${{ secrets.OKTETO_CONTEXT }}
token: ${{ secrets.OKTETO_TOKEN }}
- name: Destroy preview environment
uses: okteto/destroy-preview@latest
with:
name: pr-${{ github.event.number }}