diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 287b178c6..143da0c9a 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -18,7 +18,10 @@ on: options: [none, major, minor, patch] default: none push: - branches: [develop, master] + branches: [develop] + pull_request: + types: [closed] + branches: [master] # Avoid multiple parallel builds for the same branch to prevent race conditions concurrency: @@ -29,7 +32,16 @@ jobs: docker-build: runs-on: ubuntu-latest if: >- - (github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master') && + ( + github.event_name == 'workflow_dispatch' || + github.ref == 'refs/heads/develop' || + ( + github.event_name == 'pull_request' && + github.event.action == 'closed' && + github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'release/version-bump-v') + ) + ) && (github.event_name != 'push' || github.actor != 'github-actions[bot]') steps: @@ -38,7 +50,7 @@ jobs: with: fetch-depth: 0 # Ensure we always have the right branch context - ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.ref }} + ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || (github.event_name == 'pull_request' && github.event.pull_request.merge_commit_sha) || github.ref }} - name: Install Rust Tools (Binaries) uses: taiki-e/install-action@v2 @@ -107,10 +119,11 @@ jobs: chmod +x ./bin/inc_version.sh if [[ "${{ github.event_name }}" == "push" ]]; then case "${{ github.ref_name }}" in - master) ./bin/inc_version.sh p ;; develop) ./bin/inc_version.sh ;; *) echo "Unsupported push branch: ${{ github.ref_name }}" >&2; exit 1 ;; esac + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "Release PR already contains the committed version bump; skipping local increment." else case "${{ github.event.inputs.choice }}" in major) ./bin/inc_version.sh m ;; @@ -120,6 +133,9 @@ jobs: fi - name: Commit version bump + if: >- + github.event_name != 'pull_request' && + !(github.event_name == 'workflow_dispatch' && github.event.inputs.branch == 'master') id: version_commit run: | git config user.name "github-actions[bot]" @@ -139,7 +155,7 @@ jobs: REPO_OWNER: ${{ github.repository_owner }} run: | chmod +x ./bin/build_docker.sh - ./bin/build_docker.sh ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.ref_name }} + ./bin/build_docker.sh ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || (github.event_name == 'pull_request' && 'master') || github.ref_name }} - name: Read project version id: version @@ -187,7 +203,11 @@ jobs: if-no-files-found: error - name: Push version bump - if: success() && steps.version_commit.outputs.did_commit == 'true' + if: >- + success() && + github.event_name != 'pull_request' && + !(github.event_name == 'workflow_dispatch' && github.event.inputs.branch == 'master') && + steps.version_commit.outputs.did_commit == 'true' run: | # Use origin HEAD to push to the correct remote branch git push origin HEAD @@ -196,7 +216,12 @@ jobs: if: >- success() && ( (github.event_name == 'workflow_dispatch' && github.event.inputs.branch == 'master') || - (github.event_name == 'push' && github.ref == 'refs/heads/master') + ( + github.event_name == 'pull_request' && + github.event.action == 'closed' && + github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'release/version-bump-v') + ) ) uses: softprops/action-gh-release@v2 with: diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml new file mode 100644 index 000000000..41734aea7 --- /dev/null +++ b/.github/workflows/release-pr.yml @@ -0,0 +1,87 @@ +name: Prepare Release PR + +permissions: + contents: write + pull-requests: write + +on: + push: + branches: [master] + +concurrency: + group: release-pr-${{ github.ref }} + cancel-in-progress: false + +jobs: + prepare-release-pr: + runs-on: ubuntu-latest + if: github.actor != 'github-actions[bot]' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: master + + - name: Detect release-version changes in push + id: detect_release_merge + run: | + BEFORE="${{ github.event.before }}" + AFTER="${{ github.sha }}" + if [[ -z "${BEFORE}" || "${BEFORE}" == "0000000000000000000000000000000000000000" ]]; then + BEFORE="${AFTER}^" + fi + + CHANGED_FILES="$(git diff --name-only "${BEFORE}" "${AFTER}" || true)" + echo "Changed files:" + printf '%s\n' "${CHANGED_FILES}" + + if printf '%s\n' "${CHANGED_FILES}" | grep -Eq '^(Cargo\.toml|Cargo\.lock|backend/Cargo\.toml|backend/Cargo\.lock|frontend/Cargo\.toml|shared/Cargo\.toml)$'; then + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Detected version-file change on master push; assuming merged release PR." + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + + - name: Install Rust Tools + if: steps.detect_release_merge.outputs.skip != 'true' + uses: taiki-e/install-action@v2 + with: + tool: cargo-edit + + - name: Install Rust Toolchain + if: steps.detect_release_merge.outputs.skip != 'true' + uses: dtolnay/rust-toolchain@stable + + - name: Bump minor version for release PR + if: steps.detect_release_merge.outputs.skip != 'true' + run: | + chmod +x ./bin/inc_version.sh + ./bin/inc_version.sh p + + - name: Read bumped version + if: steps.detect_release_merge.outputs.skip != 'true' + id: version + run: | + VERSION=$(grep -Po '^version\s*=\s*"\K[0-9\.]+' ./Cargo.toml) + echo "value=${VERSION}" >> "$GITHUB_OUTPUT" + + - name: Create release PR + if: steps.detect_release_merge.outputs.skip != 'true' + uses: peter-evans/create-pull-request@v7 + with: + branch: release/version-bump-v${{ steps.version.outputs.value }} + base: master + title: "ci: bump version v${{ steps.version.outputs.value }}" + commit-message: "ci: bump version v${{ steps.version.outputs.value }}" + body: | + Automated release version bump for `master`. + + This PR was created after a non-release push to `master` and prepares the next release version. + + Version change: + - minor bump: `${{ steps.version.outputs.value }}` + + After merging this PR, the release workflow will build and publish the release from `master`. + delete-branch: false