feat: Release with PR (#11)

This commit is contained in:
Cezary Olborski
2025-09-23 15:36:02 +08:00
committed by GitHub
parent 6f431e514d
commit 4dea7ec895
5 changed files with 332 additions and 210 deletions

View File

@@ -1,5 +1,5 @@
---
name: continuous integration
name: CI
on:
pull_request:

View File

@@ -1,4 +1,4 @@
name: cuda builder
name: Cuda Docker Image Builder
on:
workflow_dispatch:

185
.github/workflows/release-proposal.yml vendored Normal file
View File

@@ -0,0 +1,185 @@
---
name: Release Proposal
env:
CARGO_TERM_COLOR: always
on:
workflow_dispatch:
inputs:
target_branch:
description: 'Target branch for the PR (default: main)'
required: false
type: string
default: 'main'
version_type:
description: 'Type of version bump'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
- custom
custom_version:
description: 'Custom version string (e.g., 1.2.3). Only used if version_type is "custom".'
required: false
is_draft:
description: 'Is this a draft release?'
required: true
type: boolean
default: false
jobs:
calculate-next-version:
name: 🧮 Calculate Next Version
runs-on: ubuntu-latest
outputs:
new_version: ${{ steps.versioner.outputs.new_version }}
new_tag: ${{ steps.versioner.outputs.new_tag }}
commit_sha_short: ${{ steps.vars.outputs.commit_sha_short }}
source_branch: ${{ steps.vars.outputs.source_branch }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
- name: Get current branch and commit SHA
id: vars
run: |
echo "commit_sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
echo "source_branch=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT
- name: Get current version from Cargo.toml
id: current_version
run: |
current=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
echo "current=$current" >> $GITHUB_OUTPUT
echo "Current version: $current"
- name: Calculate new version
id: versioner
env:
CURRENT_VERSION: ${{ steps.current_version.outputs.current }}
VERSION_TYPE: ${{ github.event.inputs.version_type }}
CUSTOM_VERSION: ${{ github.event.inputs.custom_version }}
run: |
if [[ "$VERSION_TYPE" == "custom" ]]; then
if [[ -z "$CUSTOM_VERSION" ]]; then
echo "Error: Custom version is selected but no custom_version string provided."
exit 1
fi
new_version="$CUSTOM_VERSION"
else
# Parse current version
IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
major=${VERSION_PARTS[0]}
minor=${VERSION_PARTS[1]}
patch=${VERSION_PARTS[2]}
# Calculate new version
case $VERSION_TYPE in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
esac
new_version="$major.$minor.$patch"
fi
new_tag="v$new_version"
echo "new_version=$new_version" >> $GITHUB_OUTPUT
echo "new_tag=$new_tag" >> $GITHUB_OUTPUT
echo "New version: $new_version"
echo "New tag: $new_tag"
update-cargo-toml:
name: 📝 Update version files
needs: calculate-next-version
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install cargo-edit
run: cargo install cargo-edit --locked
- name: Create version bump branch and PR
env:
NEW_VERSION: ${{ needs.calculate-next-version.outputs.new_version }}
NEW_TAG: ${{ needs.calculate-next-version.outputs.new_tag }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SOURCE_BRANCH: ${{ needs.calculate-next-version.outputs.source_branch }}
TARGET_BRANCH: ${{ github.event.inputs.target_branch }}
run: |
set -ex
branch_name="release/${NEW_TAG}"
# Create new branch from source branch
git checkout "$SOURCE_BRANCH"
git checkout -b "$branch_name"
# Update version in Cargo.toml
echo "Updating Cargo.toml to version: $NEW_VERSION"
cargo set-version "$NEW_VERSION"
# Commit changes
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git add Cargo.toml Cargo.lock
git commit -m "bump version to $NEW_TAG"
git push origin "$branch_name"
# Prepare PR title and body
PR_TITLE="Release $NEW_TAG"
PR_BODY="Automated version bump for release $NEW_TAG.
## Overview
- Version bump: ${{ github.event.inputs.version_type }}
- Type: ${{ github.event.inputs.version_type }}
- Draft: ${{ github.event.inputs.is_draft }}
## What changed
- Updated version in Cargo.toml and Cargo.lock
## Validation
- [ ] Version number is correct
- [ ] All tests pass
- [ ] Ready for release
Triggered by workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# Prepare labels
PR_LABELS="release-proposal"
if [[ "${{ github.event.inputs.is_draft }}" == "true" ]]; then
PR_LABELS="$PR_LABELS,draft-release"
fi
gh pr create \
--title "$PR_TITLE" \
--body "$PR_BODY" \
--base "$TARGET_BRANCH" \
--head "$branch_name" \
--label "$PR_LABELS"

145
.github/workflows/release-publish.yml vendored Normal file
View File

@@ -0,0 +1,145 @@
---
name: Release Publish
on:
pull_request:
types: [closed]
branches:
- main
permissions:
contents: write
packages: write
env:
CARGO_TERM_COLOR: always
jobs:
create-tag:
name: Create Tag
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release-proposal')
runs-on: ubuntu-latest
outputs:
version: ${{ steps.extract_version.outputs.version }}
tag: ${{ steps.extract_version.outputs.tag }}
is_draft: ${{ steps.extract_version.outputs.is_draft }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version from PR title
id: extract_version
run: |
# Extract version from PR title (format: "Release vX.Y.Z")
VERSION_TAG=$(echo "${{ github.event.pull_request.title }}" | grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+')
if [ -z "$VERSION_TAG" ]; then
echo "Error: Could not extract version from PR title: ${{ github.event.pull_request.title }}"
exit 1
fi
VERSION=${VERSION_TAG#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=$VERSION_TAG" >> $GITHUB_OUTPUT
# Check if this is a draft release
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'draft-release') }}" == "true" ]]; then
echo "is_draft=true" >> $GITHUB_OUTPUT
else
echo "is_draft=false" >> $GITHUB_OUTPUT
fi
echo "Extracted version: $VERSION"
echo "Extracted tag: $VERSION_TAG"
- name: Create and push tag
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git tag -a "${{ steps.extract_version.outputs.tag }}" -m "Release ${{ steps.extract_version.outputs.tag }}"
git push origin "${{ steps.extract_version.outputs.tag }}"
build:
needs: create-tag
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
binary_name: quantus-miner
asset_name: quantus-miner-linux-x86_64
- os: windows-latest
target: x86_64-pc-windows-msvc
binary_name: quantus-miner.exe
asset_name: quantus-miner-windows-x86_64.exe
- os: macos-latest
target: aarch64-apple-darwin
binary_name: quantus-miner
asset_name: quantus-miner-macos-aarch64
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.create-tag.outputs.tag }}
- name: setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.target }}
- name: build binary
run: cargo build --release --locked --target ${{ matrix.target }}
- name: prepare binary
shell: bash
run: |
cd target/${{ matrix.target }}/release
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
cp ${{ matrix.binary_name }} ${{ matrix.asset_name }}
else
cp ${{ matrix.binary_name }} ${{ matrix.asset_name }}
strip ${{ matrix.asset_name }}
fi
- name: upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: target/${{ matrix.target }}/release/${{ matrix.asset_name }}
release:
needs: [create-tag, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.create-tag.outputs.tag }}
- name: download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ needs.create-tag.outputs.tag }}
IS_DRAFT: ${{ needs.create-tag.outputs.is_draft }}
run: |
# Prepare draft flag
if [[ "$IS_DRAFT" == "true" ]]; then
DRAFT_FLAG="--draft"
else
DRAFT_FLAG=""
fi
# Create release with all artifacts
gh release create "$TAG" \
--title "Release $TAG" \
--generate-notes \
$DRAFT_FLAG \
artifacts/quantus-miner-linux-x86_64/quantus-miner-linux-x86_64 \
artifacts/quantus-miner-windows-x86_64.exe/quantus-miner-windows-x86_64.exe \
artifacts/quantus-miner-macos-aarch64/quantus-miner-macos-aarch64

View File

@@ -1,208 +0,0 @@
---
name: release
on:
workflow_dispatch:
inputs:
version_bump:
description: 'Version bump type'
required: true
default: 'patch'
type: choice
options:
- patch
- minor
- major
permissions:
contents: write
packages: write
env:
CARGO_TERM_COLOR: always
jobs:
# Run CI checks if releasing from non-main branch
ci-validation:
runs-on: ubuntu-latest
if: github.ref != 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt, clippy
- name: install taplo
run: cargo install taplo-cli --locked
- name: format checks
run: |
taplo format --check --config taplo.toml
cargo fmt --all -- --check
timeout-minutes: 5
- name: clippy
run: cargo clippy --locked --workspace --all-targets -- -D warnings
timeout-minutes: 30
- name: build and test
run: |
cargo build --locked --workspace
cargo test --locked --workspace
timeout-minutes: 90
version:
runs-on: ubuntu-latest
needs: [ci-validation]
if: always() && (needs.ci-validation.result == 'success' || needs.ci-validation.result == 'skipped')
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- name: install cargo-edit
run: cargo install cargo-edit --locked
- name: get current version
id: current_version
run: |
current=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')
echo "current=$current" >> $GITHUB_OUTPUT
- name: calculate new version
id: version
run: |
current="${{ steps.current_version.outputs.current }}"
bump_type="${{ github.event.inputs.version_bump }}"
# Parse current version
IFS='.' read -ra VERSION_PARTS <<< "$current"
major=${VERSION_PARTS[0]}
minor=${VERSION_PARTS[1]}
patch=${VERSION_PARTS[2]}
# Calculate new version
case $bump_type in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
esac
new_version="$major.$minor.$patch"
tag="v$new_version"
echo "version=$new_version" >> $GITHUB_OUTPUT
echo "tag=$tag" >> $GITHUB_OUTPUT
echo "New version will be: $new_version"
- name: update Cargo.toml version
run: |
cargo set-version ${{ steps.version.outputs.version }}
- name: commit version bump
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add Cargo.toml Cargo.lock
git commit -m "bump version to v${{ steps.version.outputs.version }}"
git push origin main
- name: create tag
run: |
git tag ${{ steps.version.outputs.tag }}
git push origin ${{ steps.version.outputs.tag }}
build:
needs: version
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
binary_name: quantus-miner
asset_name: quantus-miner-linux-x86_64
- os: windows-latest
target: x86_64-pc-windows-msvc
binary_name: quantus-miner.exe
asset_name: quantus-miner-windows-x86_64.exe
- os: macos-latest
target: aarch64-apple-darwin
binary_name: quantus-miner
asset_name: quantus-miner-macos-aarch64
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.version.outputs.tag }}
- name: setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.target }}
- name: build binary
run: cargo build --release --locked --target ${{ matrix.target }}
- name: prepare binary
shell: bash
run: |
cd target/${{ matrix.target }}/release
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
cp ${{ matrix.binary_name }} ${{ matrix.asset_name }}
else
cp ${{ matrix.binary_name }} ${{ matrix.asset_name }}
strip ${{ matrix.asset_name }}
fi
- name: upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset_name }}
path: target/${{ matrix.target }}/release/${{ matrix.asset_name }}
release:
needs: [version, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.version.outputs.tag }}
- name: download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: create release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.version.outputs.tag }}
name: Release ${{ needs.version.outputs.tag }}
draft: false
prerelease: false
generate_release_notes: true
files: |
artifacts/quantus-miner-linux-x86_64/quantus-miner-linux-x86_64
artifacts/quantus-miner-windows-x86_64.exe/quantus-miner-windows-x86_64.exe
artifacts/quantus-miner-macos-aarch64/quantus-miner-macos-aarch64
env:
GITHUB_TOKEN: ${{ secrets.ADMIN_PAT }}