Skip to content

Commit 1e206f8

Browse files
feat: update release flow to make sure only runner releases are marked as latest (#180)
* feat: update release flow * feat: add script to clean up alpha releases
1 parent 61ae355 commit 1e206f8

7 files changed

Lines changed: 243 additions & 43 deletions

File tree

.github/workflows/bump-action.yml

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Create draft release
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
plan:
7+
required: true
8+
type: string
9+
10+
jobs:
11+
main:
12+
runs-on: ubuntu-latest
13+
env:
14+
PLAN: ${{ inputs.plan }}
15+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
steps:
17+
- name: Plan details
18+
run: |
19+
echo "Plan details: $PLAN"
20+
21+
- uses: actions/checkout@v4
22+
23+
- name: Create draft release
24+
run: |
25+
RELEASE_TAG=$(echo ${PLAN} | jq -r '.announcement_tag')
26+
ANNOUNCEMENT_TITLE=$(echo ${PLAN} | jq -r '.announcement_title')
27+
ANNOUNCEMENT_BODY=$(echo ${PLAN} | jq -r '.announcement_github_body')
28+
29+
# Write body to file to avoid quoting issues
30+
echo "$ANNOUNCEMENT_BODY" > /tmp/release-notes.txt
31+
32+
echo "Creating draft release ${RELEASE_TAG}"
33+
# The release will be undrafted by cargo-dist after it has uploaded the artifacts
34+
gh release create "${RELEASE_TAG}" \
35+
--draft \
36+
--title "${ANNOUNCEMENT_TITLE}" \
37+
--notes-file /tmp/release-notes.txt
38+
39+
echo "Release created successfully"
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Bump action runner version
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
plan:
7+
required: true
8+
type: string
9+
10+
jobs:
11+
main:
12+
runs-on: ubuntu-latest
13+
env:
14+
PLAN: ${{ inputs.plan }}
15+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
steps:
17+
- name: Plan details
18+
run: |
19+
echo "Plan details: $PLAN"
20+
21+
- name: Check if runner was released
22+
id: check_runner
23+
run: |
24+
IS_PRE_RELEASE=$(echo ${PLAN} | jq '.announcement_is_prerelease')
25+
NEW_VERSION=$(echo ${PLAN} | jq -r '.releases[] | select(.app_name == "codspeed-runner") | .app_version')
26+
RELEASE_TAG=$(echo ${PLAN} | jq -r '.announcement_tag')
27+
28+
echo "is_pre_release=${IS_PRE_RELEASE}" >> "$GITHUB_OUTPUT"
29+
echo "new_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
30+
echo "release_tag=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"
31+
32+
if [ "${IS_PRE_RELEASE}" == "true" ]; then
33+
echo "runner_released=false" >> "$GITHUB_OUTPUT"
34+
echo "Pre-release detected, cargo-dist has already undrafted this release, nothing more to do"
35+
elif [ -z "${NEW_VERSION}" ] || [ "${NEW_VERSION}" == "null" ]; then
36+
echo "runner_released=false" >> "$GITHUB_OUTPUT"
37+
echo "A package other than the runner has been released, cargo-dist has already undrafted this release, nothing more to do"
38+
else
39+
echo "runner_released=true" >> "$GITHUB_OUTPUT"
40+
echo "Runner version ${NEW_VERSION} was released"
41+
fi
42+
43+
- name: Mark release as latest
44+
if: steps.check_runner.outputs.runner_released == 'true'
45+
run: |
46+
RELEASE_TAG="${{ steps.check_runner.outputs.release_tag }}"
47+
REPO_OWNER=$(echo ${PLAN} | jq -r '.releases[0].hosting.github.owner')
48+
REPO_NAME=$(echo ${PLAN} | jq -r '.releases[0].hosting.github.repo')
49+
echo "Marking release ${RELEASE_TAG} as latest"
50+
gh release edit "${RELEASE_TAG}" -R "${REPO_OWNER}/${REPO_NAME}" --latest
51+
52+
- name: Trigger action runner version bump workflow
53+
if: steps.check_runner.outputs.runner_released == 'true'
54+
env:
55+
GH_TOKEN: ${{ secrets.PAT_CODSPEED_ACTION }}
56+
run: |
57+
NEW_VERSION="${{ steps.check_runner.outputs.new_version }}"
58+
echo "Triggering action runner version bump for version ${NEW_VERSION}"
59+
# Trigger the bump-runner-version workflow in the CodSpeedHQ/action repository
60+
gh workflow run bump-runner-version.yml -R CodSpeedHQ/action -f version=${NEW_VERSION}

.github/workflows/release.yml

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
# * uploads those artifacts to temporary workflow zip
1111
# * on success, uploads the artifacts to a GitHub Release
1212
#
13-
# Note that the GitHub Release will be created with a generated
14-
# title/body based on your changelogs.
13+
# Note that a GitHub Release with this tag is assumed to exist as a draft
14+
# with the appropriate title/body, and will be undrafted for you.
1515

1616
name: Release
1717
permissions:
@@ -165,11 +165,21 @@ jobs:
165165
${{ steps.cargo-dist.outputs.paths }}
166166
${{ env.BUILD_MANIFEST_NAME }}
167167
168+
custom-create-draft-release:
169+
needs:
170+
- plan
171+
if: ${{ needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload' }}
172+
uses: ./.github/workflows/create-draft-release.yml
173+
with:
174+
plan: ${{ needs.plan.outputs.val }}
175+
secrets: inherit
176+
168177
# Build and package all the platform-agnostic(ish) things
169178
build-global-artifacts:
170179
needs:
171180
- plan
172181
- build-local-artifacts
182+
- custom-create-draft-release
173183
runs-on: "ubuntu-22.04"
174184
env:
175185
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -216,9 +226,10 @@ jobs:
216226
needs:
217227
- plan
218228
- build-local-artifacts
229+
- custom-create-draft-release
219230
- build-global-artifacts
220231
# Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine)
221-
if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }}
232+
if: ${{ always() && needs.plan.result == 'success' && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') && (needs.custom-create-draft-release.result == 'skipped' || needs.custom-create-draft-release.result == 'success') }}
222233
env:
223234
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
224235
runs-on: "ubuntu-22.04"
@@ -269,14 +280,12 @@ jobs:
269280
- name: Create GitHub Release
270281
env:
271282
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
272-
ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
273-
ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
274283
RELEASE_COMMIT: "${{ github.sha }}"
275284
run: |
276-
# Write and read notes from a file to avoid quoting breaking things
277-
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
285+
# If we're editing a release in place, we need to upload things ahead of time
286+
gh release upload "${{ needs.plan.outputs.tag }}" artifacts/*
278287
279-
gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
288+
gh release edit "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --draft=false
280289
281290
announce:
282291
needs:
@@ -295,11 +304,11 @@ jobs:
295304
persist-credentials: false
296305
submodules: recursive
297306

298-
custom-bump-action:
307+
custom-post-announce:
299308
needs:
300309
- plan
301310
- announce
302-
uses: ./.github/workflows/bump-action.yml
311+
uses: ./.github/workflows/post-announce.yml
303312
with:
304313
plan: ${{ needs.plan.outputs.val }}
305314
secrets: inherit

CONTRIBUTING.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ cargo release --execute patch
8080
cargo release --execute beta
8181
```
8282

83+
### Release Flow Details
84+
85+
When you run `cargo release --execute <version>`, the following happens:
86+
87+
1. **cargo-release** bumps the version, creates a commit and a git tag, then pushes them to GitHub
88+
2. **GitHub Actions release workflow** triggers on the tag:
89+
- Custom `cargo-dist` job creates a draft GitHub release
90+
- `cargo-dist` builds artifacts for all platforms, uploads them to the draft release, and then publishes it
91+
3. Only if it is a runner release:
92+
- Custom post announce job marks it as "latest" and triggers action repo workflow
93+
94+
This ensures only stable runner releases are marked as "latest" in GitHub.
95+
8396
## Known issue
8497

85-
If one of the crates is currenlty in beta version, for example the runner is in beta version 4.4.2-beta.1, any alpha release will fail for the any crate, saying that only minor, major or patch releases is supported.
98+
- If one of the crates is currenlty in beta version, for example the runner is in beta version 4.4.2-beta.1, any alpha release will fail for the any crate, saying that only minor, major or patch releases is supported.

dist-workspace.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@ unix-archive = ".tar.gz"
1616
# Which actions to run on pull requests
1717
pr-run-mode = "plan"
1818
# Post-announce jobs to run in CI
19-
post-announce-jobs = ["./bump-action"]
19+
post-announce-jobs = ["./post-announce"]
2020
# Path that installers should place binaries in
2121
install-path = "CARGO_HOME"
2222
# Whether to install an updater program
2323
install-updater = false
2424
# Build only the required packages, and individually
2525
precise-builds = true
26+
# Don't create GitHub releases, we handle that manually to manually control which release is marked as latest
27+
create-release = false
28+
# Use the stage just after plan because we need its output to create the draft release
29+
local-artifacts-jobs = ["./create-draft-release"]
2630

2731
[dist.github-custom-runners]
2832
aarch64-unknown-linux-musl = "buildjet-2vcpu-ubuntu-2204-arm"

scripts/cleanup_alpha.sh

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "=== Alpha Release Cleanup Script ==="
5+
echo ""
6+
7+
# Fetch all alpha releases
8+
echo "Fetching alpha releases..."
9+
RELEASES=$(gh release list --limit 1000 | grep "alpha" | awk -F'\t' '{print $3}' || true)
10+
11+
# Fetch all alpha tags
12+
echo "Fetching alpha tags..."
13+
git fetch --tags 2>/dev/null || true
14+
TAGS=$(git tag -l "*alpha*" || true)
15+
16+
# Combine and get unique names
17+
ALL_ITEMS=$(echo -e "$RELEASES\n$TAGS" | sort -u | grep -v '^$' || true)
18+
19+
echo ""
20+
echo "========================================="
21+
echo "FOUND ITEMS:"
22+
echo "========================================="
23+
echo ""
24+
25+
if [ -z "$ALL_ITEMS" ]; then
26+
echo "No alpha releases or tags found."
27+
exit 0
28+
fi
29+
30+
# Display each item with its status
31+
for ITEM in $ALL_ITEMS; do
32+
HAS_RELEASE=""
33+
HAS_TAG=""
34+
35+
if echo "$RELEASES" | grep -q "^${ITEM}$"; then
36+
HAS_RELEASE=""
37+
else
38+
HAS_RELEASE=""
39+
fi
40+
41+
if echo "$TAGS" | grep -q "^${ITEM}$"; then
42+
HAS_TAG=""
43+
else
44+
HAS_TAG=""
45+
fi
46+
47+
echo " - $ITEM [Release: $HAS_RELEASE | Tag: $HAS_TAG]"
48+
done
49+
50+
echo ""
51+
echo "========================================="
52+
echo ""
53+
54+
# Process each item
55+
for ITEM in $ALL_ITEMS; do
56+
HAS_RELEASE=false
57+
HAS_TAG=false
58+
59+
if echo "$RELEASES" | grep -q "^${ITEM}$"; then
60+
HAS_RELEASE=true
61+
fi
62+
63+
if echo "$TAGS" | grep -q "^${ITEM}$"; then
64+
HAS_TAG=true
65+
fi
66+
67+
read -p "Delete '$ITEM'? (y/N) " -n 1 -r
68+
echo ""
69+
70+
if [[ $REPLY =~ ^[Yy]$ ]]; then
71+
# Delete release if it exists
72+
if [ "$HAS_RELEASE" = true ]; then
73+
echo -n " Deleting release... "
74+
if gh release delete "$ITEM" --yes 2>/dev/null; then
75+
echo "✓ deleted"
76+
else
77+
echo "✗ failed"
78+
fi
79+
fi
80+
81+
# Delete remote tag if it exists
82+
if [ "$HAS_TAG" = true ]; then
83+
echo -n " Deleting remote tag... "
84+
if git push origin ":refs/tags/$ITEM" 2>/dev/null; then
85+
echo "✓ deleted"
86+
else
87+
echo "✗ failed (may not exist on remote)"
88+
fi
89+
90+
# Delete local tag
91+
echo -n " Deleting local tag... "
92+
if git tag -d "$ITEM" 2>/dev/null; then
93+
echo "✓ deleted"
94+
else
95+
echo "✗ failed"
96+
fi
97+
fi
98+
else
99+
echo " Skipped."
100+
fi
101+
echo ""
102+
done
103+
104+
echo "========================================="
105+
echo "✓ Cleanup complete!"
106+
echo "========================================="

0 commit comments

Comments
 (0)