Skip to content

style(plugin): fix import ordering for Enabled re-export #3877

style(plugin): fix import ordering for Enabled re-export

style(plugin): fix import ordering for Enabled re-export #3877

Workflow file for this run

# Test workflow — exercises `cargo xtask release prepare` and the prep-PR
# flow on a GitHub Actions runner. Designed to graduate to `dev` later
# (renamed and minus the push trigger), so the inputs and shape match what
# the eventual `release-dispatch.yml` will expect.
#
# Two trigger paths:
#
# - `workflow_dispatch` — the future graduation path. Won't actually fire
# until this file lands on the default branch (`dev`). Keeps the inputs
# in place so the call shape is locked in.
#
# - `push` to `abernix/test-prep-action-*` — the current sandbox. Picks
# `version` from the branch-name suffix and `dry_run` from a commit
# message marker (`[execute]` opts in to actually opening a PR).
#
# Defaults to **dry-run**: prepares, diffs, logs auto-tag would-do — does
# not commit, push, or open a PR unless explicitly opted in.
name: Release: prep

Check failure on line 19 in .github/workflows/release-prep.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/release-prep.yml

Invalid workflow file

You have an error in your yaml syntax on line 19
on:
workflow_dispatch:
inputs:
version:
description: "Target version (e.g., 2.14.0)"
required: true
type: string
dry_run:
description: "Read-only run — don't commit, push, or open the prep PR"
required: false
default: true
type: boolean
pre_release:
description: "Pre-release prep — skip CHANGELOG generation; push the version-bump commit directly to the dispatched branch (no prep PR)"
required: false
default: false
type: boolean
push:
branches:
- "abernix/test-prep-action-*"
jobs:
test-prep:
runs-on: ubuntu-latest
permissions:
contents: write # to push the prep branch (when not dry-run)
pull-requests: write # to open the prep PR (when not dry-run)
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
# No persisted credentials — keeps apollo-bot2's PAT out of the
# default remote URL so it isn't implicitly available to every
# subsequent step. The one step that needs write access to a
# protected branch (pre-release prep push) supplies the PAT
# inline via env at push time.
persist-credentials: false
- name: Resolve version + mode
id: vars
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION='${{ inputs.version }}'
DRY_RUN='${{ inputs.dry_run }}'
PRE_RELEASE='${{ inputs.pre_release }}'
else
# Branch name like abernix/test-prep-action-2.14.0 → version 2.14.0
VERSION="${GITHUB_REF_NAME##*-}"
# Default dry-run unless commit message contains `[execute]`.
if git log -1 --format=%B "$GITHUB_SHA" | grep -qF '[execute]'; then
DRY_RUN=false
else
DRY_RUN=true
fi
# Auto-detect pre-release from semver suffix (e.g. 2.14.2-rc.0).
if echo "$VERSION" | grep -q -- '-'; then
PRE_RELEASE=true
else
PRE_RELEASE=false
fi
fi
echo "Resolved: version=$VERSION dry_run=$DRY_RUN pre_release=$PRE_RELEASE"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "dry_run=$DRY_RUN" >> "$GITHUB_OUTPUT"
echo "pre_release=$PRE_RELEASE" >> "$GITHUB_OUTPUT"
# ---------------------------------------------------------------------
# Diagnostic: list available env var NAMES (values redacted by GHA for
# secrets) so we can confirm what's plumbed in. Helpful for sanity-
# checking that secrets like APOLLO_BOT2_GITHUB_PAT are wired up.
# ---------------------------------------------------------------------
- name: Log env variable names (values redacted)
env:
# Surface the secret here so it shows up in the env list when set.
# GHA still redacts the actual value in logs.
APOLLO_BOT2_GITHUB_PAT: ${{ secrets.APOLLO_BOT2_GITHUB_PAT }}
run: |
echo "::group::Environment variable names"
env | cut -d= -f1 | sort
echo "::endgroup::"
echo
if [ -n "${APOLLO_BOT2_GITHUB_PAT:-}" ]; then
echo "✓ APOLLO_BOT2_GITHUB_PAT is set (token length: ${#APOLLO_BOT2_GITHUB_PAT})"
else
echo "✗ APOLLO_BOT2_GITHUB_PAT is NOT set — add it as a repo secret to enable apollo-bot2 auth."
fi
# ---------------------------------------------------------------------
# Auth check: prove APOLLO_BOT2_GITHUB_PAT actually authenticates as
# the apollo-bot2 user. Read-only — just calls /user. This is the
# gate before we can trust this PAT for tag-push in a future workflow.
# ---------------------------------------------------------------------
- name: Authenticate as apollo-bot2
env:
GH_TOKEN: ${{ secrets.APOLLO_BOT2_GITHUB_PAT }}
run: |
set -euo pipefail
if [ -z "${GH_TOKEN:-}" ]; then
echo "::warning::APOLLO_BOT2_GITHUB_PAT secret not configured — skipping auth check."
echo " Configure it (Settings → Secrets and variables → Actions) to enable this step."
exit 0
fi
echo "Attempting to authenticate as apollo-bot2..."
IDENTITY=$(gh api user --jq '"login=\(.login) id=\(.id) type=\(.type)"')
echo "✓ Authenticated: $IDENTITY"
# Loud failure if it's NOT apollo-bot2 — catches the wrong-PAT case.
case "$IDENTITY" in
*login=apollo-bot2*) echo " Identity matches expectation (apollo-bot2)." ;;
*) echo "::error::Authenticated user is not apollo-bot2. Check the PAT owner." ; exit 1 ;;
esac
- name: Install dev environment (mise)
uses: jdx/mise-action@v4
- name: Show toolchain
run: |
rustc --version
cargo --version
helm version --short
helm-docs --version || true
cargo about --version || true
cargo deny --version || true
- name: Run release prepare (no commit, no push)
run: |
set -euo pipefail
if [ '${{ steps.vars.outputs.pre_release }}' = 'true' ]; then
cargo xtask release prepare --pre-release '${{ steps.vars.outputs.version }}'
else
cargo xtask release prepare '${{ steps.vars.outputs.version }}'
fi
- name: Show resulting diff
run: |
echo "::group::git diff"
git diff
echo "::endgroup::"
echo "::group::git status"
git status --short
echo "::endgroup::"
- name: Verify diff is non-empty
run: |
if [ -z "$(git status --porcelain)" ]; then
echo "::error::release prepare produced no changes — that's suspicious."
exit 1
fi
- name: Verify CHANGELOG.md gained a v${{ steps.vars.outputs.version }} entry
if: steps.vars.outputs.pre_release != 'true'
run: |
VERSION='${{ steps.vars.outputs.version }}'
if ! grep -q "^# \[${VERSION}\]" CHANGELOG.md; then
echo "::error::CHANGELOG.md is missing the v${VERSION} heading."
exit 1
fi
echo "Found v${VERSION} heading in CHANGELOG.md"
- name: Verify CHANGELOG.md was NOT modified (pre-release)
if: steps.vars.outputs.pre_release == 'true'
run: |
if ! git diff --quiet -- CHANGELOG.md; then
echo "::error::Pre-release prep should not modify CHANGELOG.md, but it did."
echo " This usually means the --pre-release flag was lost or the xtask changed behavior."
git diff -- CHANGELOG.md | head -40
exit 1
fi
echo "CHANGELOG.md untouched, as expected for a pre-release."
# ---------------------------------------------------------------------
# Auto-tag observability (logs only — does not push tags).
#
# The eventual `auto-tag-release.yml` workflow (M2) fires on push to
# `main`/`main-v*` and tags the merge commit's second parent. Auth for
# actual tag pushes likely needs `apollo-bot2`, not the default
# github-actions[bot] — that's a separate M2 problem.
#
# For now: log what auto-tag WOULD do, including the exact commit SHA.
# ---------------------------------------------------------------------
- name: Log what auto-tag would do (including exact SHA)
run: |
set -euo pipefail
VERSION='${{ steps.vars.outputs.version }}'
# `release prepare` has set apollo-router/Cargo.toml to the target
# version. In production, auto-tag reads this from the version
# branch's tip (the merge commit's second parent on main).
PREPARED_VERSION=$(grep '^version = ' apollo-router/Cargo.toml | head -1 | cut -d'"' -f2)
PREPARED_SHA=$(git rev-parse HEAD)
echo "::group::Auto-tag would-do analysis"
echo "Prepared apollo-router version: $PREPARED_VERSION"
echo "Prepared commit SHA: $PREPARED_SHA"
echo "Branch ref: ${GITHUB_REF_NAME}"
echo "Triggering commit ($GITHUB_SHA): $(git log -1 --format='%s' "$GITHUB_SHA")"
echo
# Latest released tag on origin — proxy for "main's current version"
# since we're not running on main directly. Use `for-each-ref --count=1`
# instead of `git tag ... | head -1` to avoid SIGPIPE under pipefail
# when the tag list is long.
LATEST_TAG=$(git for-each-ref --count=1 --sort=-v:refname \
--format='%(refname:short)' \
'refs/tags/v*' --no-contains HEAD)
LATEST_VERSION="${LATEST_TAG#v}"
echo "Latest release tag (proxy for main's current version): ${LATEST_TAG:-<none>}"
if [ -z "$LATEST_VERSION" ]; then
DECISION="WOULD TAG v$PREPARED_VERSION (first release on this line)"
elif [ "$PREPARED_VERSION" = "$LATEST_VERSION" ]; then
DECISION="WOULD SKIP — prepared version equals latest tag (no version change)"
else
if git rev-parse "v$PREPARED_VERSION" >/dev/null 2>&1; then
EXISTING_SHA=$(git rev-parse "v$PREPARED_VERSION")
DECISION="WOULD SKIP — tag v$PREPARED_VERSION already exists at $EXISTING_SHA (idempotent)"
else
DECISION="WOULD TAG v$PREPARED_VERSION"
fi
fi
echo
echo "Decision: $DECISION"
echo
# The actual tag-target SHA for the future merge to main is NOT this
# commit — it's the second parent of the merge commit on main. After
# the prep PR squash-merges to ${VERSION}, that branch's HEAD becomes
# a new SHA, and that new SHA is what gets tagged when the release
# PR (${VERSION} → main) merges.
echo "Note on tag-target SHA:"
echo " - In production, auto-tag tags the SECOND PARENT of the merge"
echo " commit on main: \$(git rev-parse \$MERGE_COMMIT^2)."
echo " - That SHA equals ${VERSION}'s HEAD at merge time, which can"
echo " only be known after the prep PR squash-merges and any other"
echo " backports land. The current HEAD ($PREPARED_SHA) is just"
echo " a preview snapshot, not the final tag target."
echo "::endgroup::"
echo
echo "Reminder: actual tag push from CI requires apollo-bot2's PAT,"
echo "not the default github-actions[bot]. Until that's wired up,"
echo "a human pushes the tag manually after the merge to main."
# ---------------------------------------------------------------------
# Below this point: only runs when explicitly opted in.
# ---------------------------------------------------------------------
- name: Stop here in dry-run mode
if: steps.vars.outputs.dry_run == 'true'
run: |
echo "Dry-run mode — not committing, pushing, or opening the prep PR."
echo " - workflow_dispatch: pass dry_run=false to actually run"
echo " - push trigger: include '[execute]' in commit message"
# =====================================================================
# Pre-release path: push the version-bump commit directly to the
# dispatched branch. Used for RC/preview cuts where there's nothing
# for a human reviewer to look at — just version bumps, no CHANGELOG
# changes — and a separate prep PR is just ceremony.
#
# The push step is the only place apollo-bot2's PAT is exposed: a
# fresh remote URL with the token baked in is used for that single
# `git push` and the token is left out of any persistent config.
# =====================================================================
- name: Commit prep on the dispatched branch (pre-release)
if: steps.vars.outputs.dry_run != 'true' && steps.vars.outputs.pre_release == 'true'
run: |
set -euo pipefail
git config user.name "apollo-bot2"
git config user.email "apollo-bot2@users.noreply.github.com"
git add -A
git commit -m "prep release: v${{ steps.vars.outputs.version }}"
- name: Push prep commit directly to ${{ github.ref_name }} (pre-release)
if: steps.vars.outputs.dry_run != 'true' && steps.vars.outputs.pre_release == 'true'
env:
APOLLO_BOT2_GITHUB_PAT: ${{ secrets.APOLLO_BOT2_GITHUB_PAT }}
run: |
set -euo pipefail
if [ -z "${APOLLO_BOT2_GITHUB_PAT:-}" ]; then
echo "::error::APOLLO_BOT2_GITHUB_PAT secret is required to push to a protected release branch."
exit 1
fi
# PAT-bearing URL only used for this single push command — never
# persisted into the local repo's git config.
git push \
"https://x-access-token:${APOLLO_BOT2_GITHUB_PAT}@github.com/${GITHUB_REPOSITORY}.git" \
"HEAD:${GITHUB_REF_NAME}"
echo "Pushed prep commit directly to ${GITHUB_REF_NAME} as apollo-bot2."
# =====================================================================
# Final-release path: existing fresh-branch + open-PR flow. Reviewers
# need to look at the CHANGELOG entries before they hit the release
# branch, so we don't push direct here.
# =====================================================================
- name: Commit prep on a fresh branch (final release)
if: steps.vars.outputs.dry_run != 'true' && steps.vars.outputs.pre_release != 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
PREP_BRANCH="prep-${{ steps.vars.outputs.version }}"
git checkout -b "$PREP_BRANCH"
git add -A
git commit -m "prep release: v${{ steps.vars.outputs.version }}"
echo "PREP_BRANCH=$PREP_BRANCH" >> "$GITHUB_ENV"
- name: Push prep branch (final release)
if: steps.vars.outputs.dry_run != 'true' && steps.vars.outputs.pre_release != 'true'
env:
APOLLO_BOT2_GITHUB_PAT: ${{ secrets.APOLLO_BOT2_GITHUB_PAT }}
run: |
set -euo pipefail
# New prep branch — workflow token is enough if its `contents:
# write` permission covers branch creation; fall through to bot2
# PAT if not. Either way, no PAT persisted in local git config.
if [ -n "${APOLLO_BOT2_GITHUB_PAT:-}" ]; then
REMOTE_URL="https://x-access-token:${APOLLO_BOT2_GITHUB_PAT}@github.com/${GITHUB_REPOSITORY}.git"
else
REMOTE_URL="https://x-access-token:${{ github.token }}@github.com/${GITHUB_REPOSITORY}.git"
fi
git push "$REMOTE_URL" "$PREP_BRANCH"
- name: Open prep PR (final release)
if: steps.vars.outputs.dry_run != 'true' && steps.vars.outputs.pre_release != 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION='${{ steps.vars.outputs.version }}'
CHANGELOG_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/${PREP_BRANCH}/CHANGELOG.md"
BODY=$(cat <<EOF
> **Note**
>
> When approved, this PR will merge into **the \`$VERSION\` branch** which will — upon being approved itself — merge into \`main\`.
>
> **Things to review in this PR**:
> - **[Rendered \`CHANGELOG.md\` on this branch]($CHANGELOG_URL)** — the new \`v$VERSION\` section is at the top
> - Version bumps (see _Files Changed_ for the true reality)
> - That it targets the right release branch (\`$VERSION\` in this case!)
>
> Opened automatically by the \`test-release-prep\` workflow.
EOF
)
gh pr create \
--repo "$GITHUB_REPOSITORY" \
--base "$VERSION" \
--head "$PREP_BRANCH" \
--title "prep release: v$VERSION" \
--body "$BODY"
- name: Done
run: |
if [ '${{ steps.vars.outputs.dry_run }}' = 'true' ]; then
echo "Dry-run complete. No commit, push, or PR."
elif [ '${{ steps.vars.outputs.pre_release }}' = 'true' ]; then
echo "Pre-release prep pushed directly to ${GITHUB_REF_NAME} as apollo-bot2."
else
echo "Prep PR opened from $PREP_BRANCH into ${{ steps.vars.outputs.version }}."
fi