diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..faa6e93 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,51 @@ +changelog: + exclude: + labels: + - "ignore-for-release" + categories: + - title: "⚠️ Breaking Changes" + labels: + - "breaking-change" + - title: "🔒 Security" + labels: + - "security" + - title: "🚀 Features" + labels: + - "enhancement" + - "feature" + - title: "🐛 Bug Fixes" + labels: + - "fix" + - "bug" + - title: "📝 Documentation" + labels: + - "documentation" + - title: "🎨 Style" + labels: + - "style" + - title: "♻️ Refactoring" + labels: + - "refactor" + - title: "⚡️ Performance" + labels: + - "performance" + - title: "✅ Tests" + labels: + - "test" + - title: "👷 CI" + labels: + - "ci" + - title: "🔧 Maintenance" + labels: + - "build" + - "chore" + - title: "🐙 GitHub Actions" + labels: + - "github_actions" + - title: "📦 Dependencies" + labels: + - "dependencies" + - "php" + - title: "Other Changes" + labels: + - "*" diff --git a/.github/workflows/auto-tag-new-version.yml.tpl b/.github/workflows/auto-tag-new-version.yml.tpl deleted file mode 100644 index 1fa9434..0000000 --- a/.github/workflows/auto-tag-new-version.yml.tpl +++ /dev/null @@ -1,16 +0,0 @@ -name: "Automatically tag new version" - -on: - push: - branches: - - "main" - - "**/bugfixes" - paths: - - "setup.php" - -jobs: - auto-tag-new-version: - name: "Automatically tag new version" - uses: "glpi-project/plugin-release-workflows/.github/workflows/auto-tag-new-version.yml@v1" - secrets: - github-token: "${{ secrets.AUTOTAG_TOKEN }}" diff --git a/.github/workflows/changelog.yml.tpl b/.github/workflows/changelog.yml.tpl new file mode 100644 index 0000000..93b7ffe --- /dev/null +++ b/.github/workflows/changelog.yml.tpl @@ -0,0 +1,44 @@ +name: "Changelog" + +on: + pull_request: + types: ["opened", "synchronize", "reopened", "edited", "labeled", "unlabeled"] + +permissions: + contents: "write" + pull-requests: "read" + +concurrency: + group: "changelog-pr-${{ github.event.pull_request.number }}" + cancel-in-progress: false + +jobs: + update-changelog: + name: "Add unreleased entry" + # GITHUB_TOKEN can never push to a fork's branch, so this only covers same-repo PRs + # Fork support needs a bot/App token. + if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} + runs-on: "ubuntu-latest" + steps: + - name: "Checkout" + uses: "actions/checkout@v7" + with: + ref: "${{ github.head_ref }}" + + - name: "Add changelog entry" + uses: "froozeify/gh-changelog-updater@v1" + with: + mode: "add-unreleased" + # Commit to PR branch itself + require-merged: "false" + commit-branch: "${{ github.head_ref }}" + label-mapping: | + Added=enhancement,feature + Fixed=fix,bug + Security=security + Deprecated=deprecation + Removed=removal + Changed=refactor,performance,breaking-change + default-category: "" + category-order: "Added,Changed,Deprecated,Removed,Fixed,Security" + exclude-labels: "ignore-for-changelog,ignore-for-release,dependencies,github_actions,ci,chore,build,test,documentation,style" diff --git a/.github/workflows/release.yml.tpl b/.github/workflows/release.yml.tpl index 1332e71..a2e1960 100644 --- a/.github/workflows/release.yml.tpl +++ b/.github/workflows/release.yml.tpl @@ -1,13 +1,106 @@ -name: "Publish release" +name: "Release" on: + pull_request: + types: ["opened", "synchronize"] + paths: + - "setup.php" push: + branches: + - "main" + - "**/bugfixes" tags: - - '*' + - "*" + +permissions: + contents: "write" + +concurrency: + group: "release-${{ github.event.pull_request.head.ref || github.ref }}" + cancel-in-progress: false jobs: + # Promotes CHANGELOG.md as part of the version-bump PR itself, so it lands in the same merge + # commit as the bump. Promote is only done from a PR made in the original repo, not a fork. + promote-changelog: + name: "Promote changelog for release PR" + if: >- + ${{ github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name == github.repository && + (github.event.pull_request.base.ref == 'main' || endsWith(github.event.pull_request.base.ref, '/bugfixes')) }} + runs-on: "ubuntu-latest" + steps: + - name: "Checkout PR branch" + uses: "actions/checkout@v7" + with: + ref: "${{ github.head_ref }}" + + - name: "Extract version" + run: | + VERSION=$(grep -oP "define\('PLUGIN_\w+_VERSION', '\K[^']+" setup.php) + echo "VERSION=${VERSION}" >> "$GITHUB_ENV" + + - name: "Skip if this version is already tagged" + run: | + PROMOTE=no + if [[ -n "${{ env.VERSION }}" ]] && ! git ls-remote --exit-code --tags origin "refs/tags/${{ env.VERSION }}" > /dev/null; then + PROMOTE=yes + fi + echo "PROMOTE=${PROMOTE}" >> "$GITHUB_ENV" + + - name: "Promote Unreleased changelog section" + if: ${{ env.PROMOTE == 'yes' }} + uses: "froozeify/gh-changelog-updater@v1" + with: + mode: "promote-unreleased" + version: "${{ env.VERSION }}" + # If this plugin ships -alpha/-beta/-rc pre-release tags too, set this to "false" so + # those get a changelog section as well. + skip-prerelease: "true" + skip-if-empty: "true" + keep-unreleased: "true" + commit-branch: "${{ github.head_ref }}" + + auto-tag-new-version: + name: "Automatically tag new version" + if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/') }} + uses: "glpi-project/plugin-release-workflows/.github/workflows/auto-tag-new-version.yml@v1" + secrets: + github-token: "${{ secrets.AUTOTAG_TOKEN }}" + publish-release: + name: "Publish release" + if: ${{ startsWith(github.ref, 'refs/tags/') }} permissions: contents: "write" - name: "Publish release" uses: "glpi-project/plugin-release-workflows/.github/workflows/publish-release.yml@v1" + + release-notes: + name: "Append generated notes" + needs: ["publish-release"] + if: ${{ startsWith(github.ref, 'refs/tags/') }} + runs-on: "ubuntu-latest" + permissions: + contents: "write" + steps: + - name: "Append GitHub's label-categorised notes" + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + TAG_NAME: "${{ github.ref_name }}" + run: | + set -euo pipefail + + # publish-release already wrote the compat line + "See CHANGELOG.md" pointer — keep + # it, and append GitHub's own notes below (categorised per .github/release.yml). + EXISTING_BODY=$(gh release view "${TAG_NAME}" --repo "${GITHUB_REPOSITORY}" --json body --jq '.body') + GENERATED_NOTES=$(gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" \ + --method POST \ + -f "tag_name=${TAG_NAME}" \ + --jq '.body') + + if [[ -n "${EXISTING_BODY}" ]]; then + printf '%s\n\n---\n\n%s\n' "${EXISTING_BODY}" "${GENERATED_NOTES}" > notes.md + else + printf '%s\n' "${GENERATED_NOTES}" > notes.md + fi + gh release edit "${TAG_NAME}" --repo "${GITHUB_REPOSITORY}" --notes-file notes.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2b0cd19 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased]