diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 896b757f..b68761d1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,8 @@ updates: schedule: interval: "weekly" open-pull-requests-limit: 5 + # One big PR for all action updates + groups: + all-actions: + patterns: + - "*" diff --git a/.github/workflows/monthly-release.yml b/.github/workflows/monthly-release.yml new file mode 100644 index 00000000..9b118aa2 --- /dev/null +++ b/.github/workflows/monthly-release.yml @@ -0,0 +1,118 @@ +name: Monthly 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: + check: + runs-on: ubuntu-latest + if: ${{ github.repository == 'p4lang/PI' && github.ref == 'refs/heads/main' }} + outputs: + has_commits: ${{ steps.check_commits.outputs.has_commits }} + steps: + - name: Check for new commits since latest tag + id: check_commits + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPO="${{ github.repository }}" + TAG="$(gh api "repos/${REPO}/tags" --jq '.[0].name' 2>/dev/null || echo '')" + if [ -z "$TAG" ]; then + echo "No tags found, proceeding with release." + echo "has_commits=true" >> $GITHUB_OUTPUT + else + AHEAD="$(gh api "repos/${REPO}/compare/${TAG}...main" --jq '.ahead_by')" + if [ "$AHEAD" -eq 0 ]; then + echo "No new commits since $TAG, skipping release." + echo "has_commits=false" >> $GITHUB_OUTPUT + else + echo "$AHEAD new commits since $TAG." + echo "has_commits=true" >> $GITHUB_OUTPUT + fi + fi + + release-pr: + needs: check + if: needs.check.outputs.has_commits == 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Increment version number + run: perl -i -pe 's/\b(\d+)(?=\D*$)/$1+1/e' VERSION + + - name: Get changelog + 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 + run: | + cat <<'EOF' + ${{ steps.changelog.outputs.content }} + EOF + + - name: Get version + run: | + VERSION="$(cat VERSION)" + echo "VERSION=$VERSION" >> $GITHUB_ENV + + - name: Get commit message + 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 + 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 + uses: peter-evans/create-pull-request@v8 + with: + base: main + add-paths: VERSION + 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/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 00000000..e0bfc4bc --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,54 @@ +name: Publish Release + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - "VERSION" + +# 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: + publish: + if: ${{ github.repository == 'p4lang/PI' }} + 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)" + TAG="v$(cat VERSION)" + 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 b/VERSION new file mode 100644 index 00000000..6e8bf73a --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0