Skip to content

DAT-22270: Fix Release Drafter permissions and add release publish step#502

Open
jnewton03 wants to merge 2 commits intomainfrom
bugfix/DAT-22270-release-drafter-permissions-and-publishing
Open

DAT-22270: Fix Release Drafter permissions and add release publish step#502
jnewton03 wants to merge 2 commits intomainfrom
bugfix/DAT-22270-release-drafter-permissions-and-publishing

Conversation

@jnewton03
Copy link
Contributor

@jnewton03 jnewton03 commented Feb 19, 2026

Summary

  • Fix Release Drafter permissions: Changed contents: read to contents: write in .github/workflows/release-drafter.yml so Release Drafter can create/update draft releases (was silently failing with Resource not accessible by integration)
  • Add publish-release job: Added a new publish-release job in .github/workflows/create-release.yml that publishes the draft GitHub release after all Docker images are built and pushed to all registries
  • Manual fix applied: The v5.1.0-SECURE release has been manually updated with full release notes and published

Test plan

  • Merge a test PR to main and confirm the Release Drafter workflow succeeds without "Resource not accessible" errors
  • Verify a new draft release appears in the releases page with categorized PR notes
  • On the next release, confirm the release is auto-published after images are built
  • Verify dry-run releases are NOT published (the if condition excludes dryRun == 'true')

Jira

DAT-22270

🤖 Generated with Claude Code

Fix two bugs preventing proper release notes and publishing:

1. Grant `contents: write` permission to Release Drafter workflow so it
   can create/update draft releases (was `read`, causing silent failures)
2. Add `publish-release` job to create-release.yml that publishes the
   GitHub release after all Docker images are built and pushed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

This PR fixes two bugs in GitHub Actions release automation: updating Release Drafter workflow permissions from read to write to enable draft release creation, and adding a new job to publish draft releases after Docker image builds complete.

Changes

Cohort / File(s) Summary
Release Drafter Permissions
.github/workflows/release-drafter.yml
Updated permissions.contents from read to write to grant Release Drafter permission to create and update draft releases.
Publish GitHub Release Job
.github/workflows/create-release.yml
Added new "Publish GitHub Release" job that runs after Docker image builds complete (when not in dry-run mode) and publishes draft releases by setting draft: false using the gh CLI.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

TypeCI, type: ci

Suggested reviewers

  • jandroav
  • sayaliM0412
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes both main changes: fixing Release Drafter permissions and adding a release publish step.
Description check ✅ Passed The description clearly documents both permission fix and new publish-release job with test plan and manual fix details.
Linked Issues check ✅ Passed Changes meet all acceptance criteria: Release Drafter permissions fixed (contents: read→write) and publish-release job added to publish after builds with dry-run exclusion.
Out of Scope Changes check ✅ Passed All changes are directly related to DAT-22270 objectives: permission fix for Release Drafter and new publish-release job with conditional logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/DAT-22270-release-drafter-permissions-and-publishing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Feb 19, 2026

Claude finished @jnewton03's task in 1m 17s —— View job


Review in progress

  • Read changed files
  • Analyze changes
  • Post review

@jnewton03 jnewton03 self-assigned this Feb 19, 2026
@jnewton03 jnewton03 requested a review from jandroav February 19, 2026 18:22
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/release-drafter.yml (1)

9-11: contents: write is correct for draft release creation but is overly broad for the label-prs job.

The permission change unblocks Release Drafter's ability to create/update draft releases — that's the right fix.

Minor least-privilege note: contents: write is declared at the workflow level and therefore also applies to the label-prs job, which only needs pull-requests: write. For fork PRs, GitHub silently restricts the GITHUB_TOKEN to read-only regardless, so the practical risk is low. If you want to tighten it, move permissions to the job level:

♻️ Optional: job-level permissions for least privilege
-permissions:
-  contents: write
-  pull-requests: write
+permissions: {}

 jobs:
   label-prs:
     if: github.event_name == 'pull_request'
     runs-on: ubuntu-latest
+    permissions:
+      pull-requests: write
     steps:
       ...

   draft-community:
     if: github.event_name == 'push'
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
     steps:
       ...

   draft-secure:
     if: github.event_name == 'push'
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
     steps:
       ...
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release-drafter.yml around lines 9 - 11, The
workflow-level permissions currently set "contents: write" apply to every job
(including the "label-prs" job) which is broader than needed; update the YAML so
that "contents: write" remains only on the Release Drafter job and move a
least-privilege "permissions: pull-requests: write" into the "label-prs" job
definition instead of leaving "contents: write" at the top level — keep using
the "permissions" key but assign "contents: write" to the release-drafter job
and "pull-requests: write" to the "label-prs" job so each job has only the
permissions it requires.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/create-release.yml:
- Around line 556-562: The gh release edit step can fail if the draft release or
tag doesn't exist; update the Publish Release step to first check for the
release/tag and handle missing cases gracefully: use gh release view or gh
release list to verify that "${{ steps.release-tag.outputs.tag_name }}" exists
(or that the draft created by setup-update-draft-build exists) and only run gh
release edit when present, otherwise either create the release (gh release
create) or skip with a clear log message; also add the --latest=true flag to the
gh release edit invocation to explicitly set the release as latest.
- Around line 541-562: The publish-release job can run when no Dockerfile
changes occurred; add a job-level output named changes_made on the
update-dockerfiles job (propagate the existing flag that indicates whether files
were changed) so downstream jobs can inspect it, then add a guard to the
publish-release job (the job named "publish-release") changing its if to require
needs.update-dockerfiles.outputs.changes_made == 'true' in addition to the
existing dryRun check; also add the same changes_made guard to the "Create
GitHub Release" step in the setup-update-draft-build flow (the step that uses
softprops/action-gh-release) so it won't create an orphan lightweight tag when
no changes were made.

---

Nitpick comments:
In @.github/workflows/release-drafter.yml:
- Around line 9-11: The workflow-level permissions currently set "contents:
write" apply to every job (including the "label-prs" job) which is broader than
needed; update the YAML so that "contents: write" remains only on the Release
Drafter job and move a least-privilege "permissions: pull-requests: write" into
the "label-prs" job definition instead of leaving "contents: write" at the top
level — keep using the "permissions" key but assign "contents: write" to the
release-drafter job and "pull-requests: write" to the "label-prs" job so each
job has only the permissions it requires.

Comment on lines 541 to 562
publish-release:
name: "Publish GitHub Release"
needs: [update-dockerfiles, setup-update-draft-build]
if: ${{ needs.update-dockerfiles.outputs.dryRun == 'false' }}
runs-on: ubuntu-latest
steps:
- name: Determine Release Tag
id: release-tag
run: |
if [[ "${{ needs.update-dockerfiles.outputs.releaseType }}" == "liquibase-secure-release" ]]; then
echo "tag_name=v${{ needs.update-dockerfiles.outputs.extensionVersion }}-SECURE" >> $GITHUB_OUTPUT
else
echo "tag_name=v${{ needs.update-dockerfiles.outputs.extensionVersion }}" >> $GITHUB_OUTPUT
fi

- name: Publish Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release edit "${{ steps.release-tag.outputs.tag_name }}" \
--repo "${{ github.repository }}" \
--draft=false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

publish-release can publish an unintended release when no Dockerfile changes occurred.

The if condition only checks dryRun == 'false', with no guard on changes_made. When changes_made == 'false' (no Dockerfile bump needed):

  1. Create and Push Tag is skipped (no annotated tag pushed), but
  2. Create GitHub Release in setup-update-draft-build still runs unconditionally (it has no changes_made guard either), and softprops/action-gh-release will auto-create a lightweight tag pointing to HEAD if none exists.
  3. publish-release then publishes that unintended draft.

What was previously a harmless "orphan draft" becomes a published release after this PR. This can happen on workflow re-runs or when the target version is already current.

The root fix requires two changes:

  1. Expose changes_made as a job-level output from update-dockerfiles:
🛠️ Add `changes_made` to `update-dockerfiles` job outputs (lines 55-64)
   outputs:
     releaseType: ${{ steps.collect-data.outputs.releaseType }}
     liquibaseVersion: ${{ steps.collect-data.outputs.liquibaseVersion }}
     extensionVersion: ${{ steps.collect-data.outputs.extensionVersion }}
     dryRun: ${{ steps.collect-data.outputs.dryRun }}
     minorVersion: ${{ steps.collect-data.outputs.minorVersion }}
     latestCommitSha: ${{ steps.get-latest-sha.outputs.latestCommitSha }}
     pushDockerHub: ${{ steps.collect-data.outputs.pushDockerHub }}
     pushGHCR: ${{ steps.collect-data.outputs.pushGHCR }}
     pushECR: ${{ steps.collect-data.outputs.pushECR }}
+    changes_made: ${{ steps.update-dockerfiles.outputs.changes_made }}
  1. Guard publish-release with that output:
🛠️ Add `changes_made` guard to `publish-release` (line 544)
-    if: ${{ needs.update-dockerfiles.outputs.dryRun == 'false' }}
+    if: ${{ needs.update-dockerfiles.outputs.dryRun == 'false' && needs.update-dockerfiles.outputs.changes_made == 'true' }}

Ideally the same guard should also be added to the Create GitHub Release step in setup-update-draft-build (line 341) to prevent creating orphan drafts on no-change runs, but that's a pre-existing gap and can be addressed separately.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/create-release.yml around lines 541 - 562, The
publish-release job can run when no Dockerfile changes occurred; add a job-level
output named changes_made on the update-dockerfiles job (propagate the existing
flag that indicates whether files were changed) so downstream jobs can inspect
it, then add a guard to the publish-release job (the job named
"publish-release") changing its if to require
needs.update-dockerfiles.outputs.changes_made == 'true' in addition to the
existing dryRun check; also add the same changes_made guard to the "Create
GitHub Release" step in the setup-update-draft-build flow (the step that uses
softprops/action-gh-release) so it won't create an orphan lightweight tag when
no changes were made.

Comment on lines 556 to 562
- name: Publish Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release edit "${{ steps.release-tag.outputs.tag_name }}" \
--repo "${{ github.repository }}" \
--draft=false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

gh release edit will fail hard if the release or tag doesn't exist — consider adding a check.

If the draft release was never created (e.g., due to a partial failure in setup-update-draft-build), gh release edit exits non-zero and fails the job with no actionable diagnostic. A pre-flight existence check or graceful fallback would improve resilience:

🛠️ Proposed defensive handling
      - name: Publish Release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
-          gh release edit "${{ steps.release-tag.outputs.tag_name }}" \
-            --repo "${{ github.repository }}" \
-            --draft=false
+          TAG="${{ steps.release-tag.outputs.tag_name }}"
+          if ! gh release view "${TAG}" --repo "${{ github.repository }}" &>/dev/null; then
+            echo "::warning::Release '${TAG}' not found — skipping publish."
+            exit 0
+          fi
+          gh release edit "${TAG}" \
+            --repo "${{ github.repository }}" \
+            --draft=false \
+            --latest=true

The --latest=true also makes the "latest release" designation explicit rather than relying on GitHub's auto-detection, which is preferable for a release pipeline.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/create-release.yml around lines 556 - 562, The gh release
edit step can fail if the draft release or tag doesn't exist; update the Publish
Release step to first check for the release/tag and handle missing cases
gracefully: use gh release view or gh release list to verify that "${{
steps.release-tag.outputs.tag_name }}" exists (or that the draft created by
setup-update-draft-build exists) and only run gh release edit when present,
otherwise either create the release (gh release create) or skip with a clear log
message; also add the --latest=true flag to the gh release edit invocation to
explicitly set the release as latest.

1. Expose changes_made as a job output from update-dockerfiles and add it
   as a condition on publish-release to prevent publishing unintended
   releases when no Dockerfile changes occurred (e.g., workflow re-runs)
2. Add pre-flight existence check before gh release edit so partial
   failures in setup-update-draft-build produce a warning instead of a
   hard failure
3. Add --latest=true flag for explicit latest release designation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 19, 2026

Claude finished @jnewton03's task in 1m 10s —— View job


Review complete

  • Read changed files
  • Analyze PR diff
  • Post review

LGTM. The follow-up commit (880cf02) correctly addressed the CodeRabbit concerns:

  • changes_made is now properly wired as a job-level output from update-dockerfiles (line 65), so downstream jobs can gate on it.
  • publish-release guards on both dryRun == 'false' and changes_made == 'true', preventing accidental publishing on no-op runs.
  • The defensive gh release view pre-check prevents a hard failure if the draft release doesn't exist.
  • --latest=true makes the "latest release" designation explicit.
  • The contents: write fix in release-drafter.yml is the correct minimal change to unblock Release Drafter.

One unaddressed nitpick: workflow-level contents: write in release-drafter.yml also applies to the label-prs job, which only needs pull-requests: write. Practical risk is low (GitHub auto-restricts fork PR tokens to read-only), so not a blocker. Fix this →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments