Merge pull request #6 from includeamin/support-more-configs #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Tag & Release | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| inputs: | |
| bump: | |
| description: "Version bump type (auto-detected from commits if empty)" | |
| required: false | |
| type: choice | |
| options: | |
| - "" | |
| - patch | |
| - minor | |
| - major | |
| prerelease: | |
| description: "Pre-release label (leave empty for stable)" | |
| required: false | |
| type: string | |
| permissions: | |
| contents: write | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| tag: | |
| name: Bump, Changelog & Tag | |
| # Skip runs triggered by the release bot's own commits | |
| if: "!contains(github.event.head_commit.message, 'chore(release)')" | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| tag: ${{ steps.version.outputs.tag }} | |
| skip: ${{ steps.skip_check.outputs.skip }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Configure git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Detect bump type from commits | |
| id: bump_detect | |
| if: inputs.bump == '' || inputs.bump == null | |
| run: | | |
| # Get commits since last tag | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -z "$LAST_TAG" ]; then | |
| COMMITS=$(git log --oneline --format="%s") | |
| else | |
| COMMITS=$(git log "${LAST_TAG}..HEAD" --oneline --format="%s") | |
| fi | |
| echo "Commits since last tag:" | |
| echo "$COMMITS" | |
| # Detect bump type from conventional commits | |
| BUMP="patch" | |
| if echo "$COMMITS" | grep -qiE '^[a-z]+\!:|BREAKING CHANGE'; then | |
| BUMP="major" | |
| elif echo "$COMMITS" | grep -qiE '^feat'; then | |
| BUMP="minor" | |
| fi | |
| echo "bump=${BUMP}" >> "$GITHUB_OUTPUT" | |
| echo "Detected bump type: ${BUMP}" | |
| - name: Skip if no new commits | |
| id: skip_check | |
| run: | | |
| LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
| if [ -z "$LAST_TAG" ]; then | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| COMMIT_COUNT=$(git rev-list "${LAST_TAG}..HEAD" --count) | |
| if [ "$COMMIT_COUNT" -eq 0 ] && [ -z "${{ inputs.bump }}" ]; then | |
| echo "No new commits since ${LAST_TAG}, skipping." | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "${COMMIT_COUNT} commit(s) since ${LAST_TAG}" | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Calculate next version | |
| id: version | |
| if: steps.skip_check.outputs.skip != 'true' | |
| run: | | |
| # Determine bump type: manual input takes priority, else auto-detected | |
| BUMP="${{ inputs.bump }}" | |
| if [ -z "$BUMP" ]; then | |
| BUMP="${{ steps.bump_detect.outputs.bump }}" | |
| fi | |
| # Read current version from Cargo.toml | |
| CURRENT=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/') | |
| IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT" | |
| case "$BUMP" in | |
| major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;; | |
| minor) MINOR=$((MINOR + 1)); PATCH=0 ;; | |
| patch) PATCH=$((PATCH + 1)) ;; | |
| esac | |
| VERSION="${MAJOR}.${MINOR}.${PATCH}" | |
| if [ -n "${{ inputs.prerelease }}" ]; then | |
| VERSION="${VERSION}-${{ inputs.prerelease }}" | |
| fi | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "tag=v${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "Bumping ${CURRENT} → ${VERSION} (${BUMP})" | |
| - name: Update version in Cargo.toml | |
| if: steps.skip_check.outputs.skip != 'true' | |
| run: | | |
| sed -i "0,/^version = .*/s//version = \"${{ steps.version.outputs.version }}\"/" Cargo.toml | |
| cargo check --quiet 2>/dev/null || true # regenerate Cargo.lock if present | |
| - name: Install git-cliff | |
| if: steps.skip_check.outputs.skip != 'true' | |
| uses: orhun/git-cliff-action@v4 | |
| id: changelog | |
| with: | |
| config: cliff.toml | |
| args: --tag ${{ steps.version.outputs.tag }} | |
| env: | |
| OUTPUT: CHANGELOG.md | |
| GITHUB_REPO: ${{ github.repository }} | |
| - name: Generate release notes (tag-scoped) | |
| if: steps.skip_check.outputs.skip != 'true' | |
| uses: orhun/git-cliff-action@v4 | |
| id: release_notes | |
| with: | |
| config: cliff.toml | |
| args: --latest --tag ${{ steps.version.outputs.tag }} | |
| env: | |
| GITHUB_REPO: ${{ github.repository }} | |
| - name: Commit version bump & changelog | |
| if: steps.skip_check.outputs.skip != 'true' | |
| run: | | |
| git add Cargo.toml CHANGELOG.md | |
| git commit -m "chore(release): ${{ steps.version.outputs.tag }}" | |
| git push | |
| - name: Create and push tag | |
| if: steps.skip_check.outputs.skip != 'true' | |
| run: | | |
| git tag -a "${{ steps.version.outputs.tag }}" -m "Release ${{ steps.version.outputs.tag }}" | |
| git push origin "${{ steps.version.outputs.tag }}" | |
| - name: Write release notes to file | |
| if: steps.skip_check.outputs.skip != 'true' | |
| run: echo '${{ steps.release_notes.outputs.content }}' > /tmp/release_notes.md | |
| - name: Upload release notes | |
| if: steps.skip_check.outputs.skip != 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-notes | |
| path: /tmp/release_notes.md | |
| build: | |
| name: Build ${{ matrix.target }} | |
| needs: tag | |
| if: needs.tag.outputs.skip != 'true' | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-unknown-linux-musl | |
| os: ubuntu-latest | |
| - target: aarch64-unknown-linux-musl | |
| os: ubuntu-latest | |
| - target: x86_64-apple-darwin | |
| os: macos-latest | |
| - target: aarch64-apple-darwin | |
| os: macos-latest | |
| - target: x86_64-pc-windows-msvc | |
| os: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.tag.outputs.tag }} | |
| - uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: ${{ matrix.target }} | |
| - name: Install musl tools (Linux) | |
| if: contains(matrix.target, 'musl') | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools | |
| - name: Install cross-compilation tools (aarch64-linux) | |
| if: matrix.target == 'aarch64-unknown-linux-musl' | |
| run: | | |
| sudo apt-get install -y gcc-aarch64-linux-gnu | |
| echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV | |
| - uses: Swatinem/rust-cache@v2 | |
| with: | |
| key: ${{ matrix.target }} | |
| - name: Build | |
| run: cargo build --release --target ${{ matrix.target }} | |
| - name: Package (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| cd target/${{ matrix.target }}/release | |
| tar czf ../../../openapi-aggregator-${{ matrix.target }}.tar.gz openapi-aggregator | |
| cd ../../.. | |
| - name: Package (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| Compress-Archive -Path "target/${{ matrix.target }}/release/openapi-aggregator.exe" ` | |
| -DestinationPath "openapi-aggregator-${{ matrix.target }}.zip" | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openapi-aggregator-${{ matrix.target }} | |
| path: | | |
| openapi-aggregator-*.tar.gz | |
| openapi-aggregator-*.zip | |
| release: | |
| name: Create GitHub Release | |
| needs: [tag, build] | |
| if: needs.tag.outputs.skip != 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.tag.outputs.tag }} | |
| - name: Download release notes | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: release-notes | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: openapi-aggregator-* | |
| merge-multiple: true | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.tag.outputs.tag }} | |
| name: ${{ needs.tag.outputs.tag }} | |
| body_path: release_notes.md | |
| files: | | |
| openapi-aggregator-*.tar.gz | |
| openapi-aggregator-*.zip |