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
90 changes: 90 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Continuous Integration

on:
pull_request:
paths-ignore:
- "docs/**"
- "*.md"
- "LICENSE"
push:
branches:
- main
paths-ignore:
- "docs/**"
- "*.md"
- "LICENSE"

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
CARGO_INCREMENTAL: 0
CARGO_TERM_COLOR: always

jobs:
fast-checks:
name: 🏁 Fast Checks (Format)
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
- name: Install rustfmt
run: |
rustup toolchain install
rustup component add rustfmt
- name: Cache taplo
uses: actions/cache@v5
with:
path: ~/.cargo/bin/taplo
key: taplo-cli-${{ runner.os }}
- name: Install taplo
run: |
if ! command -v taplo >/dev/null 2>&1; then
cargo install taplo-cli --locked
fi
- name: Run format checks
run: |
taplo format --check --config taplo.toml
cargo fmt --all -- --check

build-and-test-matrix:
name: 🛠️ Build & Test Matrix
needs: fast-checks
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
steps:
- uses: actions/checkout@v5
- name: Install toolchain
run: rustup toolchain install
- name: Build
run: cargo build --locked
- name: Test
run: cargo test --locked
- name: Compile benches
run: cargo bench --no-run --locked

analysis:
name: 🤖 Analysis (Clippy & Doc)
needs: fast-checks
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v5
- name: Install toolchain
run: |
rustup toolchain install
rustup component add clippy
- name: Run clippy
run: cargo clippy --locked --all-targets --all-features -- -D warnings
- name: Generate documentation
run: cargo doc --locked --no-deps --all-features
171 changes: 171 additions & 0 deletions .github/workflows/create-release-proposal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
name: Create 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 (major, minor, patch) or specify custom version"
required: true
default: "patch"
type: choice
options:
- patch
- minor
- major
- custom
custom_version:
description: 'Custom version string (e.g., v1.6.1). Only used if version_type is "custom". MUST start with "v"'
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 }}
commit_sha_short: ${{ steps.vars.outputs.commit_sha_short }}
source_branch: ${{ steps.vars.outputs.source_branch }}
steps:
- name: Checkout code
uses: actions/checkout@v5
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 latest tag
id: latest_tag
run: |
latest_semver_tag=$(git tag -l "v[0-9]*.[0-9]*.[0-9]*" | sort -V | tail -n 1)

# Historical tags are unprefixed (1.6.0). Treat those as v1.6.0.
if [ -z "$latest_semver_tag" ]; then
latest_unprefixed=$(git tag -l "[0-9]*.[0-9]*.[0-9]*" | sort -V | tail -n 1)
if [ -n "$latest_unprefixed" ]; then
latest_semver_tag="v$latest_unprefixed"
else
latest_semver_tag="v0.0.0"
fi
fi

echo "latest_tag_found=$latest_semver_tag" >> $GITHUB_OUTPUT
echo "Latest semantic version tag found: $latest_semver_tag"

- name: Calculate new version
id: versioner
env:
LATEST_TAG: ${{ steps.latest_tag.outputs.latest_tag_found }}
VERSION_TYPE: ${{ github.event.inputs.version_type }}
CUSTOM_VERSION: ${{ github.event.inputs.custom_version }}
run: |
current_version=${LATEST_TAG#v}

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
if [[ ! "$CUSTOM_VERSION" =~ ^v ]]; then
echo "Error: Custom version string MUST start with 'v' (e.g., v1.2.3)."
exit 1
fi
new_version="$CUSTOM_VERSION"
else
IFS='.' read -r major minor patch <<< "$current_version"

if [[ "$VERSION_TYPE" == "major" ]]; then
major=$((major + 1))
minor=0
patch=0
elif [[ "$VERSION_TYPE" == "minor" ]]; then
minor=$((minor + 1))
patch=0
elif [[ "$VERSION_TYPE" == "patch" ]]; then
patch=$((patch + 1))
else
echo "Error: Invalid version_type: $VERSION_TYPE"
exit 1
fi
new_version="v$major.$minor.$patch"
fi

echo "New version: $new_version"
echo "new_version=$new_version" >> $GITHUB_OUTPUT

update-version:
name: 📝 Update Version
needs: calculate-next-version
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Install toolchain
run: rustup toolchain install

- name: Create version bump branch and PR
env:
NEW_VERSION: ${{ needs.calculate-next-version.outputs.new_version }}
GITHUB_TOKEN: ${{ secrets.ADMIN_PAT }}
SOURCE_BRANCH: ${{ needs.calculate-next-version.outputs.source_branch }}
TARGET_BRANCH: ${{ github.event.inputs.target_branch }}
run: |
set -ex
new_cargo_version=${NEW_VERSION#v}
branch_name="release/${NEW_VERSION}"

git checkout "$SOURCE_BRANCH"
git checkout -b "$branch_name"

echo "Updating Cargo.toml to version: $new_cargo_version"
sed -i -E "s/^version\s*=\s*\"[0-9a-zA-Z.-]+\"/version = \"$new_cargo_version\"/" Cargo.toml

cargo update --package quantus_ur

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 "ci: Automate version bump to $NEW_VERSION"
git push origin "$branch_name"

PR_TITLE="ci: Automate version bump to $NEW_VERSION"

PR_LABELS="automated,release-proposal"
if [[ "${{ github.event.inputs.is_draft }}" == "true" ]]; then
PR_LABELS="$PR_LABELS,draft-release"
fi

gh label create automated --color "0E8A16" --description "Automated" --force
gh label create release-proposal --color "1D76DB" --description "Release proposal" --force
gh label create draft-release --color "FBCA04" --description "Draft release" --force

gh pr create \
--title "$PR_TITLE" \
--body "$(printf "Automated version bump for release %s.\\n\\n%s\\n\\nTriggered by workflow run: %s\\n\\nType: %s" "$NEW_VERSION" "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" "${{ github.event.inputs.version_type }}")" \
--base "$TARGET_BRANCH" \
--head "$branch_name" \
--label "$PR_LABELS"
Loading