Auto Release #131
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: Auto Release | |
| on: | |
| schedule: | |
| - cron: '0 4 * * *' # 12:00 UTC+8 | |
| workflow_dispatch: | |
| jobs: | |
| check-and-release: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_release: ${{ steps.check_diff.outputs.should_release }} | |
| new_tag: ${{ steps.generate_tag.outputs.new_tag }} | |
| latest_tag: ${{ steps.get_latest_tag.outputs.latest_tag }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get latest release tag | |
| id: get_latest_tag | |
| run: | | |
| latest_tag=$(git tag --sort=-version:refname | head -n 1) | |
| if [ -z "$latest_tag" ]; then | |
| echo "No previous release found" | |
| echo "latest_tag=" >> $GITHUB_OUTPUT | |
| else | |
| echo "Latest tag: $latest_tag" | |
| echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Check for changes since last release | |
| id: check_diff | |
| run: | | |
| latest_tag="${{ steps.get_latest_tag.outputs.latest_tag }}" | |
| if [ -z "$latest_tag" ]; then | |
| echo "No previous release, will create first release" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| else | |
| diff_count=$(git rev-list ${latest_tag}..HEAD --count) | |
| if [ "$diff_count" -eq "0" ]; then | |
| echo "No changes since last release ($latest_tag)" | |
| echo "should_release=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "Found $diff_count commits since last release" | |
| echo "should_release=true" >> $GITHUB_OUTPUT | |
| fi | |
| fi | |
| - name: Generate CalVer tag | |
| id: generate_tag | |
| if: steps.check_diff.outputs.should_release == 'true' | |
| run: | | |
| # Get current date (UTC+8) | |
| TZ='Asia/Shanghai' year=$(date +%Y) | |
| TZ='Asia/Shanghai' month=$(date +%m) | |
| # Find all version in this year/month with 'v' prefix and 'r' suffix | |
| prefix="v${year}.${month}.r" | |
| existing_tags=$(git tag -l "${prefix}*" | sort -V) | |
| if [ -z "$existing_tags" ]; then | |
| # No version in this year/month, start from 1 | |
| micro=1 | |
| else | |
| # Micro + 1 | |
| last_tag=$(echo "$existing_tags" | tail -n 1) | |
| last_micro=$(echo "$last_tag" | sed "s/${prefix}//") | |
| micro=$((last_micro + 1)) | |
| fi | |
| new_tag="v${year}.${month}.r${micro}" | |
| echo "New tag: $new_tag" | |
| echo "new_tag=$new_tag" >> $GITHUB_OUTPUT | |
| build: | |
| name: build artifacts | |
| needs: check-and-release | |
| if: needs.check-and-release.outputs.should_release == 'true' | |
| uses: ./.github/workflows/build.yml | |
| create-release: | |
| needs: [check-and-release, build] | |
| if: needs.check-and-release.outputs.should_release == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| pattern: nemu-*.so | |
| path: release-artifacts | |
| - name: Rename artifacts with version | |
| run: | | |
| new_tag="${{ needs.check-and-release.outputs.new_tag }}" | |
| cd release-artifacts | |
| for dir in nemu-*; do | |
| if [ -d "$dir" ]; then | |
| cd "$dir" | |
| for file in nemu-*.so; do | |
| # Extract parts: nemu-{os}-{cpu}-{type}.so | |
| # Insert version after 'nemu-': nemu-{version}-{os}-{cpu}-{type}.so | |
| new_name=$(echo "$file" | sed "s/^nemu-/nemu-${new_tag}-/") | |
| mv "$file" "$new_name" | |
| done | |
| cd .. | |
| fi | |
| done | |
| - name: Generate release notes | |
| run: | | |
| new_tag="${{ needs.check-and-release.outputs.new_tag }}" | |
| # Remove 'v' prefix for parsing | |
| version_num="${new_tag#v}" | |
| year=$(echo "$version_num" | cut -d'.' -f1) | |
| month=$(echo "$version_num" | cut -d'.' -f2) | |
| micro=$(echo "$version_num" | sed 's/.*r//') | |
| month_name=$(date -d "${year}-${month}-01" +"%B") | |
| release_date=$(TZ='Asia/Shanghai' date +"%B %-d, %Y") | |
| cat > RELEASE_NOTES.md << EOF | |
| Release ${new_tag} is the ${micro}th release in ${month_name} ${year}, released on ${release_date}. | |
| ## Artifacts | |
| The release includes pre-compiled NEMU shared objects for different configurations: | |
| - Compilation Platform: Ubuntu 20.04 (compatible with CentOS 7) | |
| - CPU: xs, xs-dual | |
| - Purpose: ref, ref-debug | |
| Each artifact is named as: \`nemu-{version}-{cpu}-{type}.so\` | |
| EOF | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.check-and-release.outputs.new_tag }} | |
| name: Release ${{ needs.check-and-release.outputs.new_tag }} | |
| body_path: RELEASE_NOTES.md | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true | |
| files: | | |
| release-artifacts/*/*.so | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |