From 6c2ab7f4a384c2cf9f371d304e0923bbaae5f598 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 22 Sep 2025 12:43:05 -0400 Subject: [PATCH] Import scheduled release workflow from bootc Hopefully this will work. Signed-off-by: Colin Walters --- .github/workflows/release.yml | 125 ++++++++++++++---------- .github/workflows/scheduled-release.yml | 112 +++++++++++++++++++++ 2 files changed, 185 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/scheduled-release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c2f6e53f5..0aea46a59 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,42 +1,92 @@ 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 @@ -44,7 +94,7 @@ jobs: ### 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 \`\`\` @@ -56,35 +106,6 @@ 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 }} @@ -92,5 +113,5 @@ jobs: 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 \ No newline at end of file diff --git a/.github/workflows/scheduled-release.yml b/.github/workflows/scheduled-release.yml new file mode 100644 index 000000000..a272a0439 --- /dev/null +++ b/.github/workflows/scheduled-release.yml @@ -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. \ No newline at end of file