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
125 changes: 73 additions & 52 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,50 +1,100 @@
name: Release

on:
push:
tags:
- 'v*.*.*'
- 'v*.*.*-*'
pull_request:
types: [closed]

permissions:
contents: write

jobs:
create-release:
name: Create GitHub Release
release:
name: Create Release
if: |
(github.event_name == 'pull_request' &&
github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'release'))
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.get-version.outputs.version }}
steps:
- uses: actions/checkout@v4

- name: Get version from tag
id: get-version
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Extract version
id: extract_version
run: |
VERSION=${GITHUB_REF_NAME#v}
# Extract version from crates/kit/Cargo.toml
VERSION=$(cargo read-manifest --manifest-path crates/kit/Cargo.toml | jq -r '.version')

# Validate version format
if ! echo "$VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' >/dev/null; then
echo "Error: Invalid version format in Cargo.toml: $VERSION"
exit 1
fi

echo "Extracted version: $VERSION"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"

echo "TAG_NAME=v$VERSION" >> $GITHUB_OUTPUT

- name: Create and push tag
run: |
VERSION="${{ steps.extract_version.outputs.version }}"
TAG_NAME="v$VERSION"

if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
echo "Tag $TAG_NAME already exists"
exit 0
fi

git tag -a -m "Release $VERSION" "$TAG_NAME"
git push origin "$TAG_NAME"

echo "Successfully created and pushed tag $TAG_NAME"

- name: Install dependencies
run: |
sudo apt update
sudo apt install -y just pkg-config go-md2man libssl-dev

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache build artifacts
uses: Swatinem/rust-cache@v2
with:
key: release-build

- name: Build and archive
run: |
just build
just archive
env:
CARGO_PROFILE_RELEASE_LTO: true
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1

- name: Create release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.get-version.outputs.version }}"
VERSION="${{ steps.extract_version.outputs.version }}"
TAG_NAME="${{ steps.extract_version.outputs.TAG_NAME }}"
PRERELEASE=""
if [[ "$VERSION" == *"-"* ]]; then
PRERELEASE="--prerelease"
fi

gh release create "${{ github.ref_name }}" \
--title "Release ${{ github.ref_name }}" \
--notes "Release ${{ github.ref_name }}
gh release create "$TAG_NAME" \
--title "Release $TAG_NAME" \
--notes "Release $TAG_NAME

## Installation

Download the appropriate binary for your platform from the assets below.

### Linux x86_64 (glibc)
\`\`\`bash
curl -LO https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/bcvk-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/${{ github.repository }}/releases/download/$TAG_NAME/bcvk-x86_64-unknown-linux-gnu.tar.gz
tar xzf bcvk-x86_64-unknown-linux-gnu.tar.gz
sudo mv bcvk-x86_64-unknown-linux-gnu /usr/local/bin/bcvk
\`\`\`
Expand All @@ -56,41 +106,12 @@ jobs:
" \
$PRERELEASE

build-release-binaries:
name: Build release binaries
needs: create-release
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt update
sudo apt install -y just pkg-config go-md2man libssl-dev

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache build artifacts
uses: Swatinem/rust-cache@v2
with:
key: release-build

- name: Build and archive
run: |
just build
just archive
env:
CARGO_PROFILE_RELEASE_LTO: true
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 1

- name: Upload to release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd target
for file in bcvk-*.tar.gz bcvk-*.tar.gz.sha256; do
echo "Uploading $file"
gh release upload "${{ github.ref_name }}" "$file" --clobber
gh release upload "${{ steps.extract_version.outputs.TAG_NAME }}" "$file" --clobber
done
112 changes: 112 additions & 0 deletions .github/workflows/scheduled-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Create Release PR

on:
schedule:
# Run every 3 weeks on Monday at 8:00 AM UTC
# Note: GitHub Actions doesn't support "every 3 weeks" directly,
# so we use a workaround by running weekly and checking if it's been 3 weeks
- cron: '0 8 * * 1'
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.2.0). Leave empty to auto-increment.'
required: false
type: string

permissions:
contents: write
pull-requests: write

jobs:
create-release-pr:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Check if it's time for a release
id: check_schedule
run: |
# For manual workflow dispatch, always proceed
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "should_release=true" >> $GITHUB_OUTPUT
exit 0
fi

START_DATE="2025-09-22" # start of a 3 week sprint
START_TIMESTAMP=$(date -d "$START_DATE" +%s)
CURRENT_TIMESTAMP=$(date +%s)
# Add 12 hour buffer (43200 seconds) to account for scheduling delays
ADJUSTED_TIMESTAMP=$((CURRENT_TIMESTAMP + 43200))
DAYS_SINCE_START=$(( (ADJUSTED_TIMESTAMP - START_TIMESTAMP) / 86400 ))
WEEKS_SINCE_START=$(( DAYS_SINCE_START / 7 ))

echo "Days since start date ($START_DATE): $DAYS_SINCE_START"
echo "Weeks since start date: $WEEKS_SINCE_START"

# Release every 3 weeks
if [ $WEEKS_SINCE_START -gt 0 ] && [ $((WEEKS_SINCE_START % 3)) -eq 0 ]; then
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "should_release=false" >> $GITHUB_OUTPUT
fi

- name: Setup Rust
if: steps.check_schedule.outputs.should_release == 'true'
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-edit
if: steps.check_schedule.outputs.should_release == 'true'
run: cargo install cargo-edit

- name: Generate release changes
id: create_commit
if: steps.check_schedule.outputs.should_release == 'true'
env:
INPUT_VERSION: ${{ github.event.inputs.version }}
run: |
# If version is provided via workflow dispatch, validate and use it
if [ -n "$INPUT_VERSION" ]; then
VERSION="$INPUT_VERSION"
# Validate version format strictly
if ! echo "$VERSION" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' >/dev/null; then
echo "Error: Invalid version format. Expected X.Y.Z (e.g., 0.2.0)"
exit 1
fi
cargo set-version --manifest-path crates/kit/Cargo.toml --package bcvk "$VERSION"
else
# default to bump the minor since that is most common
cargo set-version --manifest-path crates/kit/Cargo.toml --package bcvk --bump minor
VERSION=$(cargo read-manifest --manifest-path crates/kit/Cargo.toml | jq -r '.version')
fi

cargo update --workspace
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT

- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
env:
VERSION: ${{ steps.create_commit.outputs.VERSION }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: "Release ${{ env.VERSION }}"
commit-message: "Release ${{ env.VERSION }}"
branch: "release-${{ env.VERSION }}"
delete-branch: true
labels: release
body: |
## Release ${{ env.VERSION }}

This is an automated release PR created by the scheduled release workflow.

### Release Process

1. Review the changes in this PR
2. Ensure all tests pass
3. Merge the PR
4. The release tag will be automatically created when this PR is merged

The release workflow will automatically trigger when the tag is pushed.