diff --git a/.github/workflows/reusable-create-release-notes.yml b/.github/workflows/reusable-create-release-notes.yml index 416a4da..431a2ea 100644 --- a/.github/workflows/reusable-create-release-notes.yml +++ b/.github/workflows/reusable-create-release-notes.yml @@ -6,13 +6,20 @@ on: required: true type: string description: Tag to be used as the latest release anchor point. Can be new or existing. + auto-clear-release-candidate-notes: + type: boolean + default: true + description: Disable this to prevent the auto management of release candidate notes workflow_dispatch: inputs: tag: required: true type: string description: Tag to be used as the latest release anchor point. Can be new or existing. - + auto-clear-release-candidate-notes: + type: boolean + default: true + description: Disable this to prevent the auto management of release candidate notes jobs: create-release: name: Create Release Notes @@ -25,6 +32,13 @@ jobs: - name: Check out code uses: actions/checkout@v4 + # We forcefully clone to retrieve the release_manager.py, so that it is available in consuming repositories + - name: Check out code + uses: actions/checkout@v4 + with: + repository: "danielebra/simple-release-notes" + path: simple-release-notes + - name: Create Release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -43,7 +57,15 @@ jobs: - name: Check out code uses: actions/checkout@v4 + # We forcefully clone to retrieve the release_manager.py, so that it is available in consuming repositories + - name: Check out code + uses: actions/checkout@v4 + with: + repository: "danielebra/simple-release-notes" + path: simple-release-notes + - name: Clear Candidate + if: ${{ inputs.auto-clear-release-candidate-notes == false }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.repository }} diff --git a/.github/workflows/reusable-update-release-candidate-notes.yml b/.github/workflows/reusable-update-release-candidate-notes.yml index de14fd3..24994ca 100644 --- a/.github/workflows/reusable-update-release-candidate-notes.yml +++ b/.github/workflows/reusable-update-release-candidate-notes.yml @@ -4,6 +4,13 @@ on: inputs: branch-with-candidate-code: type: string + outputs: + CANDIDATE_BRANCH: + value: ${{ jobs.update-candidate.outputs.CANDIDATE_BRANCH }} + description: The branch that was used to generate release notes from + CANDIDATE_COMMIT: + value: ${{ jobs.update-candidate.outputs.CANDIDATE_COMMIT }} + description: The latest commit hash from the candidate branch workflow_dispatch: inputs: branch-with-candidate-code: @@ -11,32 +18,60 @@ on: type: string jobs: - update: + update-candidate: name: Update Candidate Release Notes runs-on: ubuntu-latest permissions: id-token: write contents: write + outputs: + CANDIDATE_BRANCH: ${{ steps.candidate-branch.outputs.BRANCH }} + CANDIDATE_COMMIT: ${{ steps.fetch.outputs.LATEST_CANDIDATE_COMMIT }} steps: - name: Check out code uses: actions/checkout@v4 + # We forcefully clone to retrieve the release_manager.py, so that it is available in consuming repositories + - name: Check out code + uses: actions/checkout@v4 + with: + repository: "danielebra/simple-release-notes" + branch: enrich-notes + path: simple-release-notes + - name: Set up Git run: | git config --global user.email "action@github.com" git config --global user.name "GitHub Action" - - name: Fetch latest commit from ${{ inputs.branch-with-candidate-code }} - id: fetch-master + - name: Setup pointer to candidate branch + id: candidate-branch + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + SPECIFIED_BRANCH: ${{ inputs.branch-with-candidate-code }} + run: | + # Fall back to the default branch of the repository when a candidate branch is not provided. + if [[ -z "${SPECIFIED_BRANCH}" ]]; then + DEFAULT_BRANCH=$(python3 ./simple-release-notes/release_manager.py default-branch) + echo "Falling back the default branch of ${DEFAULT_BRANCH}" + echo "BRANCH=${DEFAULT_BRANCH}" >> $GITHUB_OUTPUT + else + echo "Using the provided branch of ${SPECIFIED_BRANCH}" + echo "BRANCH=$SPECIFIED_BRANCH" >> $GITHUB_OUTPUT + fi + + - name: Fetch latest commit from ${{ steps.candidate-branch.outputs.BRANCH }} + id: fetch run: | - git fetch origin ${{ inputs.branch-with-candidate-code }} - echo "LATEST_CANDIDATE_COMMIT=$(git rev-parse origin/${{ inputs.branch-with-candidate-code }})" >> $GITHUB_OUTPUT + git fetch origin ${{ steps.candidate-branch.outputs.BRANCH }} + echo "LATEST_CANDIDATE_COMMIT=$(git rev-parse origin/${{ steps.candidate-branch.outputs.BRANCH }})" >> $GITHUB_OUTPUT - name: Sync release-candidate tag shell: bash run: | - git tag -fa release-candidate origin/${{ inputs.branch-with-candidate-code }} -m "Update release-candidate tag" + git tag -fa release-candidate origin/${{ steps.candidate-branch.outputs.BRANCH }} -m "Update release-candidate tag" git push origin refs/tags/release-candidate --force - name: Update release candidate @@ -44,4 +79,4 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPO: ${{ github.repository }} shell: bash - run: python3 release_manager.py candidate update + run: python3 ./simple-release-notes/release_manager.py candidate update diff --git a/README.md b/README.md index 8d699ae..ad90085 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Simple Release Notes -A drop-in github action to generate release notes. - +A batteries-included and opinionated drop-in solution to generating and managing github release notes. ## Setup @@ -47,3 +46,52 @@ changelog: labels: - '*' ``` + +### Integrate + +#### Candidate + +A long-lived mutable `release-candidate` tag can optionally be managed through the action `reusable-update-release-candidate-notes.yml`. + +This will persist a single release instance for candidate changes that moves when changes are being made to your repository. + +``` yaml +jobs: + update-candidate: + name: Update Release Candidate Notes + permissions: + id-token: write + contents: write + secrets: inherit + uses: danielebra/simple-release-notes/.github/workflows/reusable-update-release-candidate-notes.yml + with: + branch-with-candidate-code: main +``` + +This image demonstrates a release candidate managed by the above workflow. + +![Release Candidate](./images/candidate.png) + +#### Latest Release + +The latest release is managed by detecting the current latest release before creating a new one. Given this spread, release notes will automatically be generated, alongside a change diff. A release will be published that is now marked as `latest`. The release title is named after the tag of the release. + +``` yaml +jobs: + create-release + name: Create Release Notes + permissions: + id-token: write + contents: write + secrets: inherit + uses: danielebra/simple-release-notes/.github/workflows/reusable-create-release-notes.yml + with: + tag: v1.0.0 +``` + +The default behaviour of the `reusable-create-release-notes` workflow will automatically clear the release notes from the candidate release. To disable candidate notes, you can opt-out of this via + +``` yaml +with: + auto-clear-release-candidate-notes: false +``` diff --git a/images/candidate.png b/images/candidate.png new file mode 100644 index 0000000..a6df3ec Binary files /dev/null and b/images/candidate.png differ