SKILL.md
name: deploying-production description: "Converts the current repository to Dune's GitHub Actions production-release pipeline: protected semantic tags, manual forward releases, approved rollbacks, environments, and bot-only tag rulesets. Use when manually invoked to migrate a repository." disable-model-invocation: true
Convert this repository to tag-based production releases
Migrate the current repository to the new production-release pipeline. The result is two manual helper workflows that create protected release tags, plus a tag-triggered production deployment workflow. Do not dispatch a helper workflow as a test: it creates a production tag.
Release model
tag-release@maincreates tags;deploy-prod@maindeploys them.- Forward release: tags
mainhead or a newer reviewed commit onmain. - Rollback: creates a new patch tag at an older reviewed commit on
main; it needs a reason and approval. - Do not create, move, or delete a release tag by hand.
- Tags must be strict semantic versions. Default prefix:
v.
| Operation | First tag / example |
| --------------- | ---------------------------------------------------------- |
| Forward release | <prefix>1.0.0; then increment minor: v1.2.3 → v1.3.0 |
| Rollback | Increment patch: v1.2.3 → v1.2.4 |
Malformed and prerelease tags are ignored. The newest strict release tag is considered current production even if its deployment fails or is cancelled.
Inspect the current repository
Before editing, verify and record:
mainrequires PR review and checks; normal users cannot push directly.- The tag-triggered production workflow exists or can be added. It uses
duneanalytics/actions/library/deploy-prod@main; note its tag pattern and production environment. - GitHub App
dune-semver-tag-bot(ID4183494) is installed on the repository. Install it before creating the tag ruleset. - The repository can access organization secrets
DUNE_SEMVER_TAG_BOT_CLIENT_IDandDUNE_SEMVER_TAG_BOT_PRIVATE_KEY. For selected-repository secrets, grant this repository access. Never read or expose their values. - Workflow authors and dispatchers are within the trusted release boundary.
- The current production environment will either be retained without reviewers or removed only after every merged workflow reference is gone.
Choose one tag family and use it everywhere:
| Family | tag-prefix | Tag trigger |
| -------- | -------------- | ------------ |
| Standard | v or omitted | v*.*.* |
| Custom | <prefix>- | <prefix>-* |
target-commit is a full 40-character SHA. It is optional for releases and required for rollbacks. The shared action verifies that the SHA is on main, that releases move forward, and that rollbacks move backward.
Add the release helpers
Create both files in this repository's .github/workflows/. Substitute service, approved runner, environments, and tag prefix. Both must use the same concurrency group.
Forward release
---
name: "Deploy <service> to prod"
on:
workflow_dispatch:
inputs:
commit:
description: "Commit SHA to deploy (head of main if empty)"
required: false
type: string
concurrency:
group: prod-tag
cancel-in-progress: false
jobs:
deploy-prod:
runs-on: <approved-runner>
permissions:
contents: read
environment:
name: <release-helper-environment>
steps:
- uses: duneanalytics/actions/library/tag-release@main
with:
mode: release
target-commit: ${{ inputs.commit }}
tag-prefix: <tag-prefix>
app-token-client-id: ${{ secrets.DUNE_SEMVER_TAG_BOT_CLIENT_ID }}
app-token-private-key: ${{ secrets.DUNE_SEMVER_TAG_BOT_PRIVATE_KEY }}
Rollback
---
name: "Roll back <service> in prod"
on:
workflow_dispatch:
inputs:
commit:
description: "Commit SHA on main to roll back to"
required: true
type: string
reason:
description: "Reason for the production rollback"
required: true
type: string
concurrency:
group: prod-tag
cancel-in-progress: false
jobs:
rollback-prod:
runs-on: <approved-runner>
permissions:
contents: read
environment:
name: <rollback-helper-environment>
steps:
- uses: duneanalytics/actions/library/tag-release@main
with:
mode: rollback
target-commit: ${{ inputs.commit }}
tag-prefix: <tag-prefix>
rollback-reason: ${{ inputs.reason }}
app-token-client-id: ${{ secrets.DUNE_SEMVER_TAG_BOT_CLIENT_ID }}
app-token-private-key: ${{ secrets.DUNE_SEMVER_TAG_BOT_PRIVATE_KEY }}
prod-tag allows one running and one pending workflow per repository; a newer pending request replaces the older one. Keep the deployment workflow tag-triggered only—do not add workflow_dispatch to it.
Add or update the tag-triggered deployment
Ensure this repository's production workflow uses duneanalytics/actions/library/deploy-prod@main. It verifies the tagged commit is on main before deploying the Flux OCI artifact.
on:
push:
tags:
- "<tag-prefix>*.*.*"
jobs:
deploy-prod:
runs-on: <approved-runner>
permissions:
id-token: write
contents: read
steps:
- name: Deploy to prod
uses: duneanalytics/actions/library/deploy-prod@main
with:
role-to-assume: <optional-aws-role-arn>
manifests-ecr-repository: <optional-ecr-repository>
manifests-directory: <optional-manifest-directory>
Omit optional inputs when defaults apply. By default the action packages the checkout's manifests-directory with flux push; use that only when it contains every production manifest.
If CI already generated and pushed the OCI artifact, promote its immutable build artifact instead. The artifact must exist in the configured ECR repository before the release tag is created.
with:
source-artifact-tag: ${{ github.sha }}
Normally this is the full SHA for the tagged commit.
Configure this repository in GitHub
Create the repository environments before merging the helper workflows. Both select branch main only.
| Environment | Required reviewers | Self-review |
| ------------------------------- | ------------------ | ----------- |
| <release-helper-environment> | None | N/A |
| <rollback-helper-environment> | Release-owner team | Disabled |
Keep administrator bypass enabled for rollback only; it is for urgent incidents and GitHub records its comment. The action records the rollback reason in the job summary.
Create an active repository tag ruleset before removing reviewers from the legacy production environment:
| Setting | Value |
| ----------------- | ------------------------------------------------------------------ |
| Target | Tags |
| Name | <service> release tags |
| Include pattern | refs/tags/<tag-prefix>*.*.* |
| Rules | Restrict creation, update, deletion |
| Only bypass actor | Integration App dune-semver-tag-bot, ID 4183494, mode always |
Never add user, team, administrator, or deploy-key bypasses. The ruleset blocks direct release tags, so merge and configure helpers first or plan a release freeze.
For the legacy production environment, either retain it in the tag workflow and remove only reviewers after the ruleset is active, or remove all merged references before deleting it. A workflow reference recreates a deleted environment.
Roll out this repository conversion
- Add helpers, documentation, and any legacy-environment change on a branch.
- Configure App installation, secret visibility, and helper environments.
- Merge the helper PR.
- Activate the bot-only tag ruleset.
- Retire reviewers or delete the legacy environment as chosen.
- Without dispatching a helper, verify both environments select
main; rollback has reviewers and no self-review; the ruleset is active with only App ID4183494; helpers usetag-release@mainand the intended prefix.
Required manual actions after the helper PR merges
Always include this callout in the completion response. Do not say the conversion is complete until these actions are confirmed:
- Activate the active bot-only tag ruleset for
refs/tags/<tag-prefix>*.*.*, allowing only App ID4183494to create, update, or delete matching tags. - Only after the ruleset is active, remove required reviewers from the retained legacy production environment, or delete it if every merged workflow reference is gone.
- Verify both helper environments still select
main; rollback requires a reviewer other than the initiator; the ruleset has no user, team, administrator, or deploy-key bypasses; and the helpers use the intended prefix. - Do not dispatch either helper as a test. It creates a production tag.
After conversion: operating releases
Forward: merge and validate in dev; dispatch the forward helper from main; leave commit empty for current main, or provide a newer reviewed full SHA; confirm the tag starts deployment.
Rollback: choose an older full main SHA; dispatch with a clear reason; obtain approval from a configured reviewer other than the initiator; confirm the patch tag starts deployment.
Keep main-triggered production-spec deployment separate from tag-triggered code deployment. A rollback pauses spec deployments because parity with the newest release tag fails. Revert the rolled-back code on main, validate in dev, then forward-release that revert to resume them.