返回 last30days-skill
prepare-release.yml
根目录 / .github / workflows / prepare-release.yml
1 name: Prepare release
2
3 # Opens a chore(release) PR that runs towncrier + lockstep version bumps.
4 # Merge of that PR is tagged by tag-release.yml; tag push / dispatch runs release.yml.
5
6 on:
7 workflow_dispatch:
8 inputs:
9 bump:
10 description: Semver bump kind (ignored when version is set)
11 required: true
12 type: choice
13 options:
14 - patch
15 - minor
16 - major
17 default: patch
18 version:
19 description: Optional explicit X.Y.Z (overrides bump)
20 required: false
21 type: string
22
23 permissions: {}
24
25 jobs:
26 prepare:
27 runs-on: ubuntu-latest
28 permissions:
29 contents: write
30 pull-requests: write
31 steps:
32 - name: Checkout
33 uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
34 with:
35 fetch-depth: 0
36 persist-credentials: false
37
38 - name: Install uv
39 uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
40
41 - name: Set up Python
42 run: uv python install 3.12
43
44 - name: Install project (towncrier)
45 run: uv sync --group dev
46
47 - name: Prepare release files
48 id: prep
49 env:
50 BUMP: ${{ inputs.bump }}
51 EXPLICIT_VERSION: ${{ inputs.version }}
52 run: |
53 set -euo pipefail
54 if [ -n "${EXPLICIT_VERSION}" ]; then
55 uv run python .github/scripts/prepare_release.py --version "${EXPLICIT_VERSION}"
56 VERSION="${EXPLICIT_VERSION}"
57 else
58 uv run python .github/scripts/prepare_release.py --bump "${BUMP}"
59 VERSION="$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")"
60 fi
61 echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
62 echo "branch=release/v${VERSION}" >> "$GITHUB_OUTPUT"
63
64 - name: Create release branch and PR
65 env:
66 GH_TOKEN: ${{ github.token }}
67 VERSION: ${{ steps.prep.outputs.version }}
68 BRANCH: ${{ steps.prep.outputs.branch }}
69 DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
70 REPOSITORY: ${{ github.repository }}
71 run: |
72 set -euo pipefail
73 git config user.name "github-actions[bot]"
74 git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
75 git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${REPOSITORY}.git"
76
77 if git ls-remote --exit-code --heads origin "${BRANCH}" >/dev/null 2>&1; then
78 echo "Branch ${BRANCH} already exists on origin — aborting to avoid clobbering."
79 exit 1
80 fi
81
82 git switch -c "${BRANCH}"
83 git add \
84 CHANGELOG.md \
85 changelog.d \
86 pyproject.toml \
87 uv.lock \
88 skills/last30days/SKILL.md \
89 .claude-plugin/plugin.json \
90 .claude-plugin/marketplace.json \
91 .codex-plugin/plugin.json \
92 .grok-plugin/plugin.json \
93 .grok-plugin/marketplace.json \
94 gemini-extension.json
95 git status --short
96 if git diff --cached --quiet; then
97 echo "No release changes staged (empty changelog.d?)."
98 exit 1
99 fi
100 git commit -m "chore(release): bump version to ${VERSION}"
101 git push -u origin HEAD
102
103 gh label create release --description "Automated version lockstep release PR" --color 0E8A16 2>/dev/null || true
104 gh label create skip-changelog --description "PR has nothing for release notes" --color BFDADC 2>/dev/null || true
105
106 BODY="$(cat <<EOF
107 ## Summary
108
109 Automated release preparation for **v${VERSION}**.
110
111 - Built \`CHANGELOG.md\` from \`changelog.d/\` via towncrier
112 - Bumped every lockstep version surface (skill, pyproject, plugin/marketplace manifests, uv.lock)
113
114 ## Test plan
115
116 - [ ] \`uv run pytest\` (CI)
117 - [ ] Confirm \`tests/test_plugin_contract.py::test_versions_match_across_manifests\` passes
118 - [ ] After merge, confirm tag \`v${VERSION}\` is created and [Release](../actions/workflows/release.yml) attaches artifacts
119
120 EOF
121 )"
122 # Strip leading spaces from heredoc indentation for readable PR body
123 BODY="$(printf '%s\n' "${BODY}" | sed 's/^ //')"
124
125 gh pr create \
126 --title "chore(release): bump version to ${VERSION}" \
127 --body "${BODY}" \
128 --label "release" \
129 --base "${DEFAULT_BRANCH}" \
130 --head "${BRANCH}"
131
131 lines YAML