Skip to content

fix(orchestrator-core): emit bare native id for plugin-resolved subjects #114

fix(orchestrator-core): emit bare native id for plugin-resolved subjects

fix(orchestrator-core): emit bare native id for plugin-resolved subjects #114

name: Auto-tag release on merge
on:
pull_request:
types: [closed]
branches: [main]
permissions:
actions: write
contents: write
env:
# GitHub Actions runner Node 20 -> Node 24 deprecation (effective 2026-06-02).
# Forces JS-based actions onto Node 24 ahead of the cutover.
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
auto-tag:
name: Tag release version
runs-on: ubuntu-latest
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/')
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version from branch name
id: version
run: |
BRANCH="${{ github.event.pull_request.head.ref }}"
VERSION="${BRANCH#release/}"
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"
echo "Auto-tagging: ${VERSION}"
- name: Check whether tag already exists
id: tag
shell: bash
run: |
if git rev-parse --verify --quiet "refs/tags/${{ steps.version.outputs.version }}" >/dev/null; then
echo "Tag ${{ steps.version.outputs.version }} already exists, skipping"
echo "exists=true" >> "${GITHUB_OUTPUT}"
else
echo "exists=false" >> "${GITHUB_OUTPUT}"
fi
# This workflow is loaded from the default branch for pull_request events,
# so a stale release branch cannot bypass the guard by lacking the script.
- name: Validate release candidate lineage before tagging
if: steps.tag.outputs.exists != 'true'
shell: bash
run: scripts/check-release-lineage.sh "${{ steps.version.outputs.version }}" HEAD
- name: Create and push tag
if: steps.tag.outputs.exists != 'true'
run: |
git config user.name "AO Release Bot"
git config user.email "noreply@launchapp.dev"
git tag "${{ steps.version.outputs.version }}" -m "Release ${{ steps.version.outputs.version }}"
git push origin "${{ steps.version.outputs.version }}"
echo "Tagged and pushed ${{ steps.version.outputs.version }}"
# Tag pushes made with GITHUB_TOKEN intentionally do not trigger another
# workflow. Dispatch the release workflow explicitly at the immutable tag
# so every successful auto-tag has a corresponding publication attempt.
# Retries are safe: an existing tag must still resolve to this exact merge.
- name: Dispatch release workflow at exact tag
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
set -euo pipefail
VERSION="${{ steps.version.outputs.version }}"
TAG_COMMIT="$(git rev-list -n 1 "${VERSION}")"
HEAD_COMMIT="$(git rev-parse HEAD)"
if [[ "${TAG_COMMIT}" != "${HEAD_COMMIT}" ]]; then
echo "::error::tag ${VERSION} resolves to ${TAG_COMMIT}, expected merged HEAD ${HEAD_COMMIT}" >&2
exit 1
fi
gh workflow run release.yml --ref "${VERSION}" -f dry_run_note="auto-tag handoff from PR #${{ github.event.pull_request.number }}"