When you need this
Create GitHub deployments from Actions when all of these are true:- You deploy a preview from a GitHub Actions workflow (not a GitHub-connected Vercel or Netlify integration).
- You want the GitHub App to start a review automatically, or to wait for a preview after an
@qa.techcomment that does not include a URL.
- Vercel, Netlify, Render, Railway, or Fly.io already posts deployment records on the PR.
- You trigger reviews with the Change Review Action and pass preview URLs in
applications_config. - You comment
@qa.tech https://preview.example.comand want that URL used immediately.
deploy record on the PR head commit is successful.
What QA.tech reads
For the PR head commit (github.event.pull_request.head.sha), QA.tech looks up GitHub deployments with task set to deploy (the API default).
Unmapped extra environments (Storybook, docs previews) are skipped when you have any mapping configured. They still block readiness until their latest status is
success.
Create deployments from GitHub Actions
1
Grant workflow permissions
The default If you extract these steps into a reusable workflow, the caller must grant the same permissions.Pull requests from forks do not get a write token on
GITHUB_TOKEN can create deployments only when the job requests write access:pull_request. Deploy those previews from a workflow in the base repository, or pass a URL with @qa.tech / the Change Review Action.2
Create the deployment, then update its status
Add these steps around your existing deploy. Replace the Deploy preview step with your platform’s command. The only requirement is that it writes
url to $GITHUB_OUTPUT.result-encoding: string keeps the deployment id a bare number. The default JSON encoding wraps it in quotes and parseInt then returns NaN.The createCommitStatus calls add a Deploy - frontend check on the PR. Context names that contain deploy, deployment, or vercel are extra readiness gates: if you include them, this workflow must set them to success or failure. You can omit both commit-status calls if you only need the Deployments API records.3
Optional: set a Vercel alias
If you assign a stable hostname after Then set
vercel deploy, write that URL to $GITHUB_OUTPUT and use it as DEPLOY_URL on the success step:DEPLOY_URL: ${{ steps.set-alias.outputs.url || steps.vercel-deploy.outputs.url }} on the success step so GitHub and QA.tech both receive the alias.Why these create-deployment flags matter
Environment protection rules (required reviewers, wait timer) still apply. If
createDeployment returns an error, check the GitHub repository Settings → Environments for that name.
Map environments to applications
After the first successful deploy, the environment name appears under Settings → Integrations → GitHub App in Mapped GitHub Environments.1
Use one stable name per application
Names like
Preview - frontend and Preview - admin map cleanly. Avoid
per-PR names such as pr-123; you would have to remap them on every pull
request.2
Assign each name to a QA.tech application
For a project with more than one application, map each GitHub environment to
the matching application so the review agent opens the correct preview URL.
3
Leave unused previews unmapped
Once any mapping exists, unmapped names (Storybook, docs) are ignored
for testing. They must still reach
success or the review waits.Multiple applications
Run one deploy job (or one reusable workflow call) per application. Give each job its ownAPP_NAME so GitHub creates distinct environments. Then map those names in Mapped GitHub Environments.
If routing by environment name is a poor fit, turn off Auto-run on PRs and pass URLs with the Change Review Action instead.
Troubleshooting
Review never starts / “waiting for a preview deployment”- The deployment
refmust be${{ github.event.pull_request.head.sha }}.github.shaonpull_requestis the merge commit, which QA.tech does not treat as the PR head. - Latest status must be
success. A leftoverpendingdeployment or aDeploy - frontendcommit status blocks readiness. environment_urlmust be anhttp://orhttps://URL on the success status.
- Confirm the success status includes
environment_url. - Map the GitHub environment name in Mapped GitHub Environments.
- If a mapping exists but this name is missing from it, QA.tech skips that deployment on purpose.
createDeployment fails or never returns an id
- Set
required_contexts: []. - Check environment protection rules on the GitHub repository Settings → Environments.
- Confirm
permissions.deployments: writeon the job (and on the reusable-workflow caller).
- Create one GitHub environment per application and map each name.
- Or pass per-application URLs with the Change Review Action.
Related documentation
- GitHub App - Automatic PR reviews that consume these deployment records
- GitHub Actions - Test Run Action and Change Review Action
- Preview Environments - How QA.tech stores per-PR URLs
- Vercel Preview Protection - Bypass headers when the preview is locked