diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..9ed718f --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,28 @@ +# .github/release.yml + +changelog: + exclude: + labels: + - ignore-for-release + categories: + - title: Breaking Changes + labels: + - breaking-change + - title: Bug Fixes + labels: + - bug + - title: Enhancements + labels: + - enhancement + - title: Python Changes + labels: + - python + - title: Dependencies + labels: + - dependencies + - title: CI/Infrastructure + labels: + - github_actions + - title: Other Changes + labels: + - "*" diff --git a/.github/workflows/ci-auto-release.yml b/.github/workflows/ci-auto-release.yml new file mode 100644 index 0000000..c5d1741 --- /dev/null +++ b/.github/workflows/ci-auto-release.yml @@ -0,0 +1,111 @@ +name: Automated Release + +on: + workflow_dispatch: + schedule: + - cron: "17 12 1 * *" # At 12:17 on day-of-month 1 (avoid top-of-hour load) + +permissions: + contents: write + pull-requests: write + +jobs: + build: + runs-on: ubuntu-latest + # Check if the event is not triggered by a fork + if: ${{ github.repository == 'p4lang/ptf' && github.ref == 'refs/heads/main' }} + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + # Fetch all history for all branches and tags + fetch-depth: 0 + + - name: Check for new commits + id: check_commits + run: | + TAG="$(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)" + COMMIT_COUNT="$(git rev-list $TAG..HEAD --count)" + echo "count=$COMMIT_COUNT" >> $GITHUB_OUTPUT + if [ "$COMMIT_COUNT" -eq 0 ]; then + echo "No new commits since $TAG, skipping release." + else + echo "$COMMIT_COUNT new commits since $TAG." + fi + + - name: Increment version number + if: steps.check_commits.outputs.count != '0' + run: perl -i -pe 's/\b(\d+)(?=\D*$)/$1+1/e' Version.txt + + - name: Get changelog + if: steps.check_commits.outputs.count != '0' + id: changelog + run: | + TAG="$(git describe --tags --abbrev=0 2>/dev/null || git rev-list --max-parents=0 HEAD)" + GIT_LOG="$(git log $TAG..HEAD --oneline --pretty=format:"- %s [%an]")" + CHANGELOG=$(cat << EOF + Changelog: + $GIT_LOG + EOF + ) + CHANGELOG="${CHANGELOG//'#'/''}" + echo "content<> "$GITHUB_OUTPUT" + echo "$CHANGELOG" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + - name: Display changelog + if: steps.check_commits.outputs.count != '0' + run: | + cat <<'EOF' + ${{ steps.changelog.outputs.content }} + EOF + + - name: Get version + if: steps.check_commits.outputs.count != '0' + run: | + VERSION="$(cat Version.txt)" + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Get commit message + if: steps.check_commits.outputs.count != '0' + id: message + run: | + COMMIT_MSG=$(cat << 'EOF' + Release v${{ env.VERSION }} + + ${{ steps.changelog.outputs.content }} + EOF + ) + echo "content<> "$GITHUB_OUTPUT" + echo "$COMMIT_MSG" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + - name: Get pull request body message + if: steps.check_commits.outputs.count != '0' + id: body + run: | + MSG=$(cat << 'EOF' + Auto-generated pull request for version ${{ env.VERSION }}. + + Please use **Squash and merge** to include the changelog in the release message. + + ${{ steps.changelog.outputs.content }} + EOF + ) + echo "content<> "$GITHUB_OUTPUT" + echo "$MSG" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + - name: Create Pull Request + if: steps.check_commits.outputs.count != '0' + uses: peter-evans/create-pull-request@v8 + with: + base: main + add-paths: Version.txt + reviewers: fruffy, jafingerhut + commit-message: ${{ steps.message.outputs.content }} + signoff: false + branch: v${{ env.VERSION }} + delete-branch: true + title: Automated Release v${{ env.VERSION }} + body: ${{ steps.body.outputs.content }} diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml new file mode 100644 index 0000000..6266f35 --- /dev/null +++ b/.github/workflows/ci-release.yml @@ -0,0 +1,54 @@ +name: GitHub Release + +on: + push: + branches: + - main + paths: + - "Version.txt" + - ".github/workflows/ci-release.yml" + +# Cancel any preceding run on the pull request. +concurrency: + group: release-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + build: + if: ${{ github.repository == 'p4lang/ptf' }} + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Get version + run: | + VERSION="$(cat Version.txt)" + TAG="v$(cat Version.txt)" + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "TAG=$TAG" >> $GITHUB_ENV + + - name: Check if tag exists + id: check_tag + run: | + TAG="${{ env.TAG }}" + if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists, skipping release creation." + echo "tag_exists=true" >> $GITHUB_OUTPUT + else + echo "Tag $TAG does not exist." + echo "tag_exists=false" >> $GITHUB_OUTPUT + fi + + - name: Release + if: steps.check_tag.outputs.tag_exists == 'false' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ env.TAG }} + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Version.txt b/Version.txt new file mode 100644 index 0000000..d9df1bb --- /dev/null +++ b/Version.txt @@ -0,0 +1 @@ +0.11.0