From 8998875f006396fcc4724363daed5e1d73ebf191 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Mon, 18 Nov 2024 11:58:48 -0500 Subject: [PATCH] Update Release Drafter for Dev Branches Changes the way release drafter handles drafting releases on repos with release branches (which have dev branches now). Ultimately, a release is drafted for the dev branch and the release branch. The releases are differentiated by both their release title and tag. - Release Branch - Title: `release-v` - Tag: `v` - Dev Branch - Title: `dev-v` - Tag: `dev-v` Note that the tag for the release branch follows the same convention as existing release tags. The "release branch" release includes all pull requests made to the dev branch with the `type:backport` label since the last "dev branch" release. For this reason, the "dev branch" and "release branch" should be released at the same time. Then, this effectively results in the "release branch" having all relevant changes since the last release. The "dev branch" release will be based at the same point in history as the "release branch" release but include all changes not just those with the `type:backport` label. The "release branch" release for the current release branch should be marked as "latest". For example, if "release/202311" and "release/202405" exist, the "release/202405" "release branch" release would be marked as latest. The `release-drafter/release-drafter` action is still used. Signed-off-by: Michael Kubacki --- .github/workflows/ReleaseDrafter.yml | 126 ++++++++++++++++-- .sync/Files.yml | 14 ++ .../release-draft/release-draft-config.yml | 14 +- .sync/workflows/leaf/release-draft.yml | 3 +- 4 files changed, 143 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ReleaseDrafter.yml b/.github/workflows/ReleaseDrafter.yml index 46764fc6..7e1ba265 100644 --- a/.github/workflows/ReleaseDrafter.yml +++ b/.github/workflows/ReleaseDrafter.yml @@ -11,10 +11,10 @@ # # 1. A "latest release branch" # - Example: `release/202405` -# - Config file: `release-draft-config-n.yml` +# - Config file: `release-draft-config-n.yml` and `release-draft-config-n-dev.yml` # 2. A "previous release branch" # - Example: `release/202311` -# - Config file: `release-draft-config-n-1.yml` +# - Config file: `release-draft-config-n-1.yml` and `release-draft-config-n-1-dev.yml` # 3. A "main branch" # - Example: `main` # - Config file: `release-draft-config.yml` @@ -68,13 +68,19 @@ jobs: run: | fileContent=$(cat "${FILE_PATH}") latestMuReleaseBranch=$(echo "$fileContent" | grep -oP '(?<=latest_mu_release_branch = ").*(?=")') + latestMuDevBranch=$(echo "$latestMuReleaseBranch" | sed 's/release/dev/') previousMuReleaseBranch=$(echo "$fileContent" | grep -oP '(?<=previous_mu_release_branch = ").*(?=")') - echo "latest_mu_branch=${latestMuReleaseBranch}" >> $GITHUB_ENV - echo "latest_mu_branch_full=refs/heads/${latestMuReleaseBranch}" >> $GITHUB_ENV - echo "previous_mu_branch=${previousMuReleaseBranch}" >> $GITHUB_ENV - echo "previous_mu_branch_full=refs/heads/${previousMuReleaseBranch}" >> $GITHUB_ENV - - name: Build a ${{ env.latest_mu_branch }} Draft - if: ${{ startsWith(github.ref, env.latest_mu_branch_full) }} + previousMuDevBranch=$(echo "$previousMuReleaseBranch" | sed 's/release/dev/') + echo "latest_mu_release_branch=${latestMuReleaseBranch}" >> $GITHUB_ENV + echo "latest_mu_dev_branch=${latestMuDevBranch}" >> $GITHUB_ENV + echo "latest_mu_dev_branch_full=refs/heads/${latestMuDevBranch}" >> $GITHUB_ENV + echo "latest_mu_release_branch_full=refs/heads/${latestMuReleaseBranch}" >> $GITHUB_ENV + echo "previous_mu_release_branch=${previousMuReleaseBranch}" >> $GITHUB_ENV + echo "previous_mu_dev_branch=${previousMuDevBranch}" >> $GITHUB_ENV + echo "previous_mu_dev_branch_full=refs/heads/${previousMuDevBranch}" >> $GITHUB_ENV + echo "previous_mu_release_branch_full=refs/heads/${previousMuReleaseBranch}" >> $GITHUB_ENV + - name: Build a ${{ env.latest_mu_release_branch }} Draft + if: ${{ startsWith(github.ref, env.latest_mu_dev_branch_full) }} id: update_draft_n uses: release-drafter/release-drafter@v6.0.0 with: @@ -82,8 +88,49 @@ jobs: config-name: release-draft-config-n.yml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Build a ${{ env.previous_mu_branch }} Draft - if: ${{ startsWith(github.ref, env.previous_mu_branch_full) }} + - name: Draft Release for Current (${{ env.latest_mu_release_branch }}) Release Branch + if: steps.update_draft_n.outcome == 'success' + run: | + # Prepare the release body + release_body_path="${{ runner.temp }}/release_body.txt" + release_body=$(cat <<'EOF' + ${{ steps.update_draft_n.outputs.body }} + EOF + ) + release_body="${release_body//\`/\\\`}" + echo "${release_body}" > $release_body_path + sed -i 's/\\`/`/g' $release_body_path + sed -i '/Full Changelog:/d' $release_body_path + + # Get the new tag and title + new_tag=$(echo "${{ steps.update_draft_n.outputs.tag_name }}" | sed 's/dev-//') + new_title=$(echo "${{ steps.update_draft_n.outputs.tag_name }}" | sed 's/dev/release/') + + # Determine the corresponding tag names + existing_tag_prefix="" + tag_regex="v([0-9]{6}).*\." + if [[ $new_tag =~ $tag_regex ]]; then + existing_tag_prefix="${BASH_REMATCH[1]}" + fi + + # Delete the template dev draft created + gh release delete "${{ steps.update_draft_n.outputs.tag_name }}" --repo ${{ github.repository }} --yes + + # Delete any existing draft releases for this release branch + for tag in $(gh release list --repo ${{ github.repository }} --json tagName,isPrerelease,isDraft --jq ".[] | select(.isDraft == true and .isPrerelease == false and (.tagName | startswith(\"v$existing_tag_prefix\"))) | .tagName"); do + gh release delete "$tag" --repo ${{ github.repository }} --yes + done + + gh release create "$new_tag" \ + --repo "${{ github.repository }}" \ + --target "${{ env.latest_mu_release_branch_full }}" \ + --title "$new_title" \ + --notes-file "$release_body_path" \ + --draft + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Build a ${{ env.previous_mu_release_branch }} Draft + if: ${{ startsWith(github.ref, env.previous_mu_dev_branch_full) }} id: update_draft_n_1 uses: release-drafter/release-drafter@v6.0.0 with: @@ -91,8 +138,65 @@ jobs: config-name: release-draft-config-n-1.yml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Draft Release for N-1 (${{ env.previous_mu_release_branch }}) Release Branch + if: steps.update_draft_n_1.outcome == 'success' + run: | + # Prepare the release body + release_body_path="${{ runner.temp }}/release_body.txt" + release_body=$(cat <<'EOF' + ${{ steps.update_draft_n_1.outputs.body }} + EOF + ) + release_body="${release_body//\`/\\\`}" + echo "${release_body}" > $release_body_path + sed -i 's/\\`/`/g' $release_body_path + sed -i '/Full Changelog:/d' $release_body_path + + # Get the new tag and title + new_tag=$(echo "${{ steps.update_draft_n_1.outputs.tag_name }}" | sed 's/dev-//') + new_title=$(echo "${{ steps.update_draft_n_1.outputs.tag_name }}" | sed 's/dev/release/') + + # Determine the corresponding tag names + existing_tag_prefix="" + tag_regex="v([0-9]{6}).*\." + if [[ $new_tag =~ $tag_regex ]]; then + existing_tag_prefix="${BASH_REMATCH[1]}" + fi + + # Delete the template dev draft created + gh release delete "${{ steps.update_draft_n_1.outputs.tag_name }}" --repo ${{ github.repository }} --yes + + # Delete any existing draft releases for this release branch + for tag in $(gh release list --repo ${{ github.repository }} --json tagName,isPrerelease,isDraft --jq ".[] | select(.isDraft == true and .isPrerelease == false and (.tagName | startswith(\"v$existing_tag_prefix\"))) | .tagName"); do + gh release delete "$tag" --repo ${{ github.repository }} --yes + done + + gh release create "$new_tag" \ + --repo "${{ github.repository }}" \ + --target "${{ env.previous_mu_release_branch_full }}" \ + --title "$new_title" \ + --notes-file "$release_body_path" \ + --draft + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create the ${{ env.latest_mu_dev_branch }} Draft + if: ${{ startsWith(github.ref, env.latest_mu_dev_branch_full) }} + uses: release-drafter/release-drafter@v6.0.0 + with: + # Note: Path is relative to .github/ + config-name: release-draft-config-n-dev.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create the ${{ env.previous_mu_dev_branch }} Draft + if: ${{ startsWith(github.ref, env.previous_mu_dev_branch_full) }} + uses: release-drafter/release-drafter@v6.0.0 + with: + # Note: Path is relative to .github/ + config-name: release-draft-config-n-1-dev.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build the New Release Draft - if: ${{ !startsWith(github.ref, 'refs/heads/release') }} + if: ${{ !startsWith(github.ref, 'refs/heads/release') && !startsWith(github.ref, 'refs/heads/dev') }} id: update_draft_non_release uses: release-drafter/release-drafter@v6.0.0 with: diff --git a/.sync/Files.yml b/.sync/Files.yml index 7a2696ec..d01a2055 100644 --- a/.sync/Files.yml +++ b/.sync/Files.yml @@ -618,11 +618,25 @@ group: - source: .sync/workflows/config/release-draft/release-draft-config.yml dest: .github/release-draft-config-n.yml template: + filter_to_backport: true + latest: true + release_branch: true + - source: .sync/workflows/config/release-draft/release-draft-config.yml + dest: .github/release-draft-config-n-dev.yml + template: + filter_to_backport: false latest: true release_branch: true - source: .sync/workflows/config/release-draft/release-draft-config.yml dest: .github/release-draft-config-n-1.yml template: + filter_to_backport: true + latest: false + release_branch: true + - source: .sync/workflows/config/release-draft/release-draft-config.yml + dest: .github/release-draft-config-n-1-dev.yml + template: + filter_to_backport: false latest: false release_branch: true repos: | diff --git a/.sync/workflows/config/release-draft/release-draft-config.yml b/.sync/workflows/config/release-draft/release-draft-config.yml index 073b7fcd..4d5b95bd 100644 --- a/.sync/workflows/config/release-draft/release-draft-config.yml +++ b/.sync/workflows/config/release-draft/release-draft-config.yml @@ -19,15 +19,25 @@ {% import '../../../Version.njk' as sync_version -%} +{%- if release_branch %} +name-template: 'dev-v$RESOLVED_VERSION' +tag-template: 'dev-v$RESOLVED_VERSION' +{% else %} name-template: 'v$RESOLVED_VERSION' tag-template: 'v$RESOLVED_VERSION' +{% endif %} {# `release_branch` applies a commitish. `latest` then determines the branch to use. -#} {# If a commitish is not specified, then the `github.ref` value is implicitly used. -#} {%- if release_branch %} -{% set release_branch = "refs/heads/" + (sync_version.latest_mu_release_branch if latest else sync_version.previous_mu_release_branch) %} -commitish: {{ release_branch }} +{%- set latest_mu_dev_branch = "refs/heads/" + (sync_version.latest_mu_release_branch | replace("release", "dev")) %} +{%- set previous_mu_dev_branch = "refs/heads/" + (sync_version.previous_mu_release_branch | replace("release", "dev")) %} +{%- set actual_branch = latest_mu_dev_branch if latest else previous_mu_dev_branch %} +commitish: {{ actual_branch }} filter-by-commitish: true +{% if filter_to_backport %} +include-labels: ["type:backport"] +{% endif %} {% endif %} template: | diff --git a/.sync/workflows/leaf/release-draft.yml b/.sync/workflows/leaf/release-draft.yml index f32a1b52..58890c17 100644 --- a/.sync/workflows/leaf/release-draft.yml +++ b/.sync/workflows/leaf/release-draft.yml @@ -25,10 +25,11 @@ name: Update Release Draft on: push: branches: - - {{ trigger_branch_name if trigger_branch_name else sync_version.latest_mu_release_branch }} + - {{ trigger_branch_name if trigger_branch_name else sync_version.latest_mu_release_branch | replace ("release", "dev") }} jobs: draft: + name: Draft Releases permissions: contents: write