Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions .github/workflows/bump-action.yml

This file was deleted.

39 changes: 39 additions & 0 deletions .github/workflows/create-draft-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Create draft release

on:
workflow_call:
inputs:
plan:
required: true
type: string

jobs:
main:
runs-on: ubuntu-latest
env:
PLAN: ${{ inputs.plan }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Plan details
run: |
echo "Plan details: $PLAN"

- uses: actions/checkout@v4

- name: Create draft release
run: |
RELEASE_TAG=$(echo ${PLAN} | jq -r '.announcement_tag')
ANNOUNCEMENT_TITLE=$(echo ${PLAN} | jq -r '.announcement_title')
ANNOUNCEMENT_BODY=$(echo ${PLAN} | jq -r '.announcement_github_body')

# Write body to file to avoid quoting issues
echo "$ANNOUNCEMENT_BODY" > /tmp/release-notes.txt

echo "Creating draft release ${RELEASE_TAG}"
# The release will be undrafted by cargo-dist after it has uploaded the artifacts
gh release create "${RELEASE_TAG}" \
--draft \
--title "${ANNOUNCEMENT_TITLE}" \
--notes-file /tmp/release-notes.txt

echo "Release created successfully"
60 changes: 60 additions & 0 deletions .github/workflows/post-announce.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Bump action runner version

on:
workflow_call:
inputs:
plan:
required: true
type: string

jobs:
main:
runs-on: ubuntu-latest
env:
PLAN: ${{ inputs.plan }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Plan details
run: |
echo "Plan details: $PLAN"

- name: Check if runner was released
id: check_runner
run: |
IS_PRE_RELEASE=$(echo ${PLAN} | jq '.announcement_is_prerelease')
NEW_VERSION=$(echo ${PLAN} | jq -r '.releases[] | select(.app_name == "codspeed-runner") | .app_version')
RELEASE_TAG=$(echo ${PLAN} | jq -r '.announcement_tag')

echo "is_pre_release=${IS_PRE_RELEASE}" >> "$GITHUB_OUTPUT"
echo "new_version=${NEW_VERSION}" >> "$GITHUB_OUTPUT"
echo "release_tag=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"

if [ "${IS_PRE_RELEASE}" == "true" ]; then
echo "runner_released=false" >> "$GITHUB_OUTPUT"
echo "Pre-release detected, cargo-dist has already undrafted this release, nothing more to do"
elif [ -z "${NEW_VERSION}" ] || [ "${NEW_VERSION}" == "null" ]; then
echo "runner_released=false" >> "$GITHUB_OUTPUT"
echo "A package other than the runner has been released, cargo-dist has already undrafted this release, nothing more to do"
else
echo "runner_released=true" >> "$GITHUB_OUTPUT"
echo "Runner version ${NEW_VERSION} was released"
fi

- name: Mark release as latest
if: steps.check_runner.outputs.runner_released == 'true'
run: |
RELEASE_TAG="${{ steps.check_runner.outputs.release_tag }}"
REPO_OWNER=$(echo ${PLAN} | jq -r '.releases[0].hosting.github.owner')
REPO_NAME=$(echo ${PLAN} | jq -r '.releases[0].hosting.github.repo')
echo "Marking release ${RELEASE_TAG} as latest"
gh release edit "${RELEASE_TAG}" -R "${REPO_OWNER}/${REPO_NAME}" --latest

- name: Trigger action runner version bump workflow
if: steps.check_runner.outputs.runner_released == 'true'
env:
GH_TOKEN: ${{ secrets.PAT_CODSPEED_ACTION }}
run: |
NEW_VERSION="${{ steps.check_runner.outputs.new_version }}"
echo "Triggering action runner version bump for version ${NEW_VERSION}"
# Trigger the bump-runner-version workflow in the CodSpeedHQ/action repository
gh workflow run bump-runner-version.yml -R CodSpeedHQ/action -f version=${NEW_VERSION}
29 changes: 19 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
# * uploads those artifacts to temporary workflow zip
# * on success, uploads the artifacts to a GitHub Release
#
# Note that the GitHub Release will be created with a generated
# title/body based on your changelogs.
# Note that a GitHub Release with this tag is assumed to exist as a draft
# with the appropriate title/body, and will be undrafted for you.

name: Release
permissions:
Expand Down Expand Up @@ -165,11 +165,21 @@ jobs:
${{ steps.cargo-dist.outputs.paths }}
${{ env.BUILD_MANIFEST_NAME }}

custom-create-draft-release:
needs:
- plan
if: ${{ needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload' }}
uses: ./.github/workflows/create-draft-release.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit

# Build and package all the platform-agnostic(ish) things
build-global-artifacts:
needs:
- plan
- build-local-artifacts
- custom-create-draft-release
runs-on: "ubuntu-22.04"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down Expand Up @@ -216,9 +226,10 @@ jobs:
needs:
- plan
- build-local-artifacts
- custom-create-draft-release
- build-global-artifacts
# Only run if we're "publishing", and only if plan, local and global didn't fail (skipped is fine)
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') }}
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') }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
runs-on: "ubuntu-22.04"
Expand Down Expand Up @@ -269,14 +280,12 @@ jobs:
- name: Create GitHub Release
env:
PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}"
ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}"
ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}"
RELEASE_COMMIT: "${{ github.sha }}"
run: |
# Write and read notes from a file to avoid quoting breaking things
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt
# If we're editing a release in place, we need to upload things ahead of time
gh release upload "${{ needs.plan.outputs.tag }}" artifacts/*

gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
gh release edit "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --draft=false

announce:
needs:
Expand All @@ -295,11 +304,11 @@ jobs:
persist-credentials: false
submodules: recursive

custom-bump-action:
custom-post-announce:
needs:
- plan
- announce
uses: ./.github/workflows/bump-action.yml
uses: ./.github/workflows/post-announce.yml
with:
plan: ${{ needs.plan.outputs.val }}
secrets: inherit
15 changes: 14 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ cargo release --execute patch
cargo release --execute beta
```

### Release Flow Details

When you run `cargo release --execute <version>`, the following happens:

1. **cargo-release** bumps the version, creates a commit and a git tag, then pushes them to GitHub
2. **GitHub Actions release workflow** triggers on the tag:
- Custom `cargo-dist` job creates a draft GitHub release
- `cargo-dist` builds artifacts for all platforms, uploads them to the draft release, and then publishes it
3. Only if it is a runner release:
- Custom post announce job marks it as "latest" and triggers action repo workflow

This ensures only stable runner releases are marked as "latest" in GitHub.

## Known issue

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.
- 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.
6 changes: 5 additions & 1 deletion dist-workspace.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ unix-archive = ".tar.gz"
# Which actions to run on pull requests
pr-run-mode = "plan"
# Post-announce jobs to run in CI
post-announce-jobs = ["./bump-action"]
post-announce-jobs = ["./post-announce"]
# Path that installers should place binaries in
install-path = "CARGO_HOME"
# Whether to install an updater program
install-updater = false
# Build only the required packages, and individually
precise-builds = true
# Don't create GitHub releases, we handle that manually to manually control which release is marked as latest
create-release = false
# Use the stage just after plan because we need its output to create the draft release
local-artifacts-jobs = ["./create-draft-release"]

[dist.github-custom-runners]
aarch64-unknown-linux-musl = "buildjet-2vcpu-ubuntu-2204-arm"
106 changes: 106 additions & 0 deletions scripts/cleanup_alpha.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/bash
set -e

echo "=== Alpha Release Cleanup Script ==="
echo ""

# Fetch all alpha releases
echo "Fetching alpha releases..."
RELEASES=$(gh release list --limit 1000 | grep "alpha" | awk -F'\t' '{print $3}' || true)

# Fetch all alpha tags
echo "Fetching alpha tags..."
git fetch --tags 2>/dev/null || true
TAGS=$(git tag -l "*alpha*" || true)

# Combine and get unique names
ALL_ITEMS=$(echo -e "$RELEASES\n$TAGS" | sort -u | grep -v '^$' || true)

echo ""
echo "========================================="
echo "FOUND ITEMS:"
echo "========================================="
echo ""

if [ -z "$ALL_ITEMS" ]; then
echo "No alpha releases or tags found."
exit 0
fi

# Display each item with its status
for ITEM in $ALL_ITEMS; do
HAS_RELEASE=""
HAS_TAG=""

if echo "$RELEASES" | grep -q "^${ITEM}$"; then
HAS_RELEASE="✓"
else
HAS_RELEASE="✗"
fi

if echo "$TAGS" | grep -q "^${ITEM}$"; then
HAS_TAG="✓"
else
HAS_TAG="✗"
fi

echo " - $ITEM [Release: $HAS_RELEASE | Tag: $HAS_TAG]"
done

echo ""
echo "========================================="
echo ""

# Process each item
for ITEM in $ALL_ITEMS; do
HAS_RELEASE=false
HAS_TAG=false

if echo "$RELEASES" | grep -q "^${ITEM}$"; then
HAS_RELEASE=true
fi

if echo "$TAGS" | grep -q "^${ITEM}$"; then
HAS_TAG=true
fi

read -p "Delete '$ITEM'? (y/N) " -n 1 -r
echo ""

if [[ $REPLY =~ ^[Yy]$ ]]; then
# Delete release if it exists
if [ "$HAS_RELEASE" = true ]; then
echo -n " Deleting release... "
if gh release delete "$ITEM" --yes 2>/dev/null; then
echo "✓ deleted"
else
echo "✗ failed"
fi
fi

# Delete remote tag if it exists
if [ "$HAS_TAG" = true ]; then
echo -n " Deleting remote tag... "
if git push origin ":refs/tags/$ITEM" 2>/dev/null; then
echo "✓ deleted"
else
echo "✗ failed (may not exist on remote)"
fi

# Delete local tag
echo -n " Deleting local tag... "
if git tag -d "$ITEM" 2>/dev/null; then
echo "✓ deleted"
else
echo "✗ failed"
fi
fi
else
echo " Skipped."
fi
echo ""
done

echo "========================================="
echo "✓ Cleanup complete!"
echo "========================================="
Loading