Skip to content

Commit 565504e

Browse files
fredbiclaude
andauthored
fix(release): fixed mono-repo workflow (#100)
* running from a fork or repo outside the go-openapi organization * allowed to run workflow with or without PGP sign-off (commits, tags) * allowed to run from a fork outside the go-openapi org (must configure bot-go-openapi github app and permissions) * fixed secret transmission to cover these use cases * gh-actions: fixed svu usage. Updated gh-actions, so that svu doesn't fail on mono-repo prefixed tags * fixed release notes * ensured git checkout is un-shallowed * git-cliff config (also applies to regular releases, not just mono-repo) * fixed commit categorization in release notes * merge commits grouped as "Other" instead of skipped (consistent count) * fix (category "Documentation"): regex overlap causing garbled group headings * fix (category "Misc."): added \bCI\b pattern to catch mid-message CI references * fix (category "Refactor"): refact rule has precedence over chore * polish cliff config categorization and contributor lists (keep all commits, but exclude bots from contributors) * release notes construction * suppressed tag annotation in module-specific sections * fixed wrong module commit scope: module sections use root tag pattern with path filtering * --exclude-path which was using absolute paths now uses relative paths with /** globs. * skip root module in Part 2 (already covered by full changelog) - was producing redundant sections. * derived module include-path from filesystem, not module names (the module name stripping used GITHUB_REPO to strip the prefix from go module paths, but this fails on forks where the repo name differs from the module path. * passed --tag to module git-cliff calls to resolve version header. When --include-path filters the commit graph, tag commits that don't touch the module's files are excluded. This prevents git-cliff from resolving the version, resulting in "unreleased" headers. * fix: tag message title/body separation for markdown rendering * style: polish monorepo release notes markdown presentation (orphaned line separators, modules with no commits, stripped module version header). Signed-off-by: Frederic BIDON <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]>
1 parent 2303360 commit 565504e

File tree

12 files changed

+153
-88
lines changed

12 files changed

+153
-88
lines changed

.cliff-monorepo.toml

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
{%- if version %}
2-
## [{{ version | trim_start_matches(pat="v") }}]({{ self::remote_url() }}/tree/{{ version }}) - {{ timestamp | date(format="%Y-%m-%d") }}
3-
{%- else %}
4-
## [unreleased]
5-
{%- endif %}
6-
{%- if message %}
7-
{%- raw %}
8-
{% endraw %}
9-
{{ message }}
10-
{%- raw %}
11-
{% endraw %}
12-
{%- endif %}
13-
14-
---
15-
161
{%- for group, commits in commits | group_by(attribute="group") %}
172
{%- raw %}
183
{% endraw %}

.cliff.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ body = """
7878
### People who contributed to this release
7979
{% endif %}
8080
{%- for contributor in github.contributors | filter(attribute="username") | sort(attribute="username") %}
81-
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
81+
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" and contributor.username != "bot-go-openapi[bot]" %}
8282
* [@{{ contributor.username }}](https://github.com/{{ contributor.username }})
8383
{%- endif %}
8484
{%- endfor %}
@@ -91,7 +91,7 @@ body = """
9191
{%- endif %}
9292
9393
{%- for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
94-
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" %}
94+
{%- if contributor.username != "dependabot[bot]" and contributor.username != "github-actions[bot]" and contributor.username != "bot-go-openapi[bot]" %}
9595
* @{{ contributor.username }} made their first contribution
9696
{%- if contributor.pr_number %}
9797
in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
@@ -144,22 +144,22 @@ protect_breaking_commits = false
144144
# Optionally sets the commit's scope and can decide to exclude commits from further processing.
145145
commit_parsers = [
146146
{ message = "^[Cc]hore\\([Rr]elease\\): prepare for", skip = true },
147-
{ message = "(^[Mm]erge)|([Mm]erge conflict)", skip = true },
147+
{ message = "(^[Mm]erge)|([Mm]erge conflict)", group = "<!-- 0B -->Other (technical)" },
148148
{ field = "author.name", pattern = "dependabot*", group = "<!-- 0A -->Updates" },
149149
{ message = "([Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
150150
{ body = "(.*[Ss]ecurity)|([Vv]uln)", group = "<!-- 08 -->Security" },
151151
{ message = "([Cc]hore\\(lint\\))|(style)|(lint)|(codeql)|(golangci)", group = "<!-- 05 -->Code quality" },
152-
{ message = "(^[Dd]oc)|((?i)readme)|(badge)|(typo)|(documentation)", group = "<!-- 03 -->Documentation" },
152+
{ message = "(^[Dd]oc)|(README)|(readme)|(badge)|(typo)", group = "<!-- 03 -->Documentation" },
153153
{ message = "(^[Ff]eat)|(^[Ee]nhancement)", group = "<!-- 00 -->Implemented enhancements" },
154-
{ message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(license)|(example)", group = "<!-- 07 -->Miscellaneous tasks" },
154+
{ message = "(^ci)|(\\(ci\\))|(fixup\\s+ci)|(fix\\s+ci)|(\\bCI\\b)|(license)|(example)", group = "<!-- 07 -->Miscellaneous tasks" },
155155
{ message = "^test", group = "<!-- 06 -->Testing" },
156156
{ message = "(^fix)|(panic)", group = "<!-- 01 -->Fixed bugs" },
157-
{ message = "(^refact)|(rework)", group = "<!-- 02 -->Refactor" },
157+
{ message = "(refact)|(rework)", group = "<!-- 02 -->Refactor" },
158158
{ message = "(^[Pp]erf)|(performance)", group = "<!-- 04 -->Performance" },
159159
{ message = "(^[Cc]hore)", group = "<!-- 07 -->Miscellaneous tasks" },
160160
{ message = "^[Rr]evert", group = "<!-- 09 -->Reverted changes" },
161161
{ message = "(upgrade.*?go)|(go\\s+version)", group = "<!-- 0A -->Updates" },
162-
{ message = ".*", group = "<!-- 0B -->Other" },
162+
{ message = ".*", group = "<!-- 0B -->Other (technical)" },
163163
]
164164
# Exclude commits that are not matched by any commit parser.
165165
filter_commits = false

.github/workflows/TODO.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* collect-test-reports should only execute if lint is successful

.github/workflows/auto-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ jobs:
133133
run: gh pr review --approve "$PR_URL"
134134
-
135135
name: Wait for all workflow runs to complete
136-
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
136+
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
137137
with:
138138
pr-url: ${{ env.PR_URL }}
139139
github-token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/bump-release-monorepo.yml

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ on:
4141
required: false
4242
type: string
4343
default: 'true'
44+
enable-commit-signing:
45+
description: |
46+
Enable PGP commit-signing by a bot user (for mono-repo releases).
47+
48+
When enabled, you must pass the GPG secrets to this workflow.
49+
required: false
50+
type: string
51+
default: 'true'
4452
cliff-config:
4553
type: string
4654
required: false
@@ -86,6 +94,22 @@ on:
8694
8795
Required when enable-tag-signing is true.
8896
required: false
97+
github-app-id:
98+
description: |
99+
GitHub App ID for bot user authentication.
100+
101+
Default for go-openapi: CI_BOT_APP_ID
102+
103+
Required to create pull requests as the bot user.
104+
required: false
105+
github-app-private-key:
106+
description: |
107+
GitHub App private key in PEM format.
108+
109+
Default for go-openapi: CI_BOT_APP_PRIVATE_KEY
110+
111+
Required to create pull requests as the bot user.
112+
required: false
89113

90114
jobs:
91115
detect-modules:
@@ -112,7 +136,7 @@ jobs:
112136
-
113137
name: Detect go mono-repo
114138
id: detect-monorepo
115-
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
139+
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
116140

117141
bump-release-single:
118142
name: Bump release (single module)
@@ -128,7 +152,10 @@ jobs:
128152
enable-tag-signing: ${{ inputs.enable-tag-signing }}
129153
cliff-config: ${{ inputs.cliff-config }}
130154
cliff-config-url: ${{ inputs.cliff-config-url }}
131-
secrets: inherit
155+
secrets:
156+
gpg-private-key: ${{ secrets.gpg-private-key }}
157+
gpg-passphrase: ${{ secrets.gpg-passphrase }}
158+
gpg-fingerprint: ${{ secrets.gpg-fingerprint }}
132159

133160
determine-next-tag:
134161
name: Determine next tag [monorepo]
@@ -168,7 +195,7 @@ jobs:
168195
-
169196
name: Determine next tag
170197
id: bump-release
171-
uses: go-openapi/gh-actions/ci-jobs/next-tag@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
198+
uses: go-openapi/gh-actions/ci-jobs/next-tag@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
172199
with:
173200
bump-patch: ${{ steps.bump-check.outputs.bump-patch }}
174201
bump-minor: ${{ steps.bump-check.outputs.bump-minor }}
@@ -184,8 +211,13 @@ jobs:
184211
uses: ./.github/workflows/prepare-release-monorepo.yml
185212
with:
186213
target-tag: ${{ needs.determine-next-tag.outputs.next-tag }}
187-
enable-commit-signing: 'true'
188-
secrets: inherit
214+
enable-commit-signing: ${{ inputs.enable-commit-signing }}
215+
secrets:
216+
github-app-id: ${{ secrets.github-app-id }}
217+
github-app-private-key: ${{ secrets.github-app-private-key }}
218+
gpg-private-key: ${{ secrets.gpg-private-key }}
219+
gpg-passphrase: ${{ secrets.gpg-passphrase }}
220+
gpg-fingerprint: ${{ secrets.gpg-fingerprint }}
189221

190222
wait-for-merge:
191223
name: Wait for PR merge [monorepo]
@@ -198,11 +230,11 @@ jobs:
198230
steps:
199231
-
200232
name: Checkout repository
201-
if: ${{ needs.prepare-modules.outputs.pull-request-operation != 'none' }} # skip if no pull request to be waited
233+
if: ${{ needs.prepare-modules.outputs.pull-request-operation != 'none' && needs.prepare-modules.outputs.pull-request-operation != 'closed' }}
202234
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
203235
-
204236
name: Wait for PR to be merged
205-
if: ${{ needs.prepare-modules.outputs.pull-request-operation != 'none' }} # skip if no pull request to be waited
237+
if: ${{ needs.prepare-modules.outputs.pull-request-operation != 'none' && needs.prepare-modules.outputs.pull-request-operation != 'closed' }}
206238
run: |
207239
echo "::notice title=waiting-for-merge::Waiting for PR ${PR_URL} to be merged"
208240
@@ -232,9 +264,16 @@ jobs:
232264
-
233265
name: Report status
234266
run: |
235-
echo "::notice title=waiting-for-merge::Waiting for PR ${PR_URL} to be merged"
267+
if [ -z "${PR_URL}" ] ; then
268+
echo "::notice title=waiting-for-merge::No PR to be waited for. Proceed."
269+
else
270+
echo "::notice title=waiting-for-merge::Waiting for PR ${PR_URL} to be merged"
271+
fi
272+
236273
if [[ "${{ needs.prepare-modules.outputs.pull-request-operation }}" == "none" ]] ; then
237274
echo "::notice title=wait-for-pr::no pull request expected. Skipped waiting."
275+
elif [[ "${{ needs.prepare-modules.outputs.pull-request-operation }}" == "closed" ]] ; then
276+
echo "::notice title=wait-for-pr::pull request closed, assumed merged. Skipped waiting."
238277
else
239278
echo "::notice title=wait-for-pr::pull request merged. Can proceed with the tagging and release"
240279
fi
@@ -268,7 +307,7 @@ jobs:
268307
-
269308
name: Configure bot credentials
270309
if: ${{ inputs.enable-tag-signing == 'true' }}
271-
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
310+
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
272311
# This is using the GPG signature of bot-go-openapi.
273312
#
274313
# For go-openapi repos (using secrets: inherit):
@@ -302,18 +341,26 @@ jobs:
302341
303342
cd "${root}"
304343
305-
# Construct the tag message
344+
# Construct the tag message.
345+
# A blank line between title and body is required for git to
346+
# distinguish %(contents:subject) from %(contents:body).
347+
# Body lines use "|" as paragraph separator (workflow inputs
348+
# do not support multiline strings).
306349
MESSAGE="${MESSAGE_TITLE}"
307350
if [[ -n "${MESSAGE_BODY}" ]] ; then
308-
BODY=$(echo "${MESSAGE_BODY}"|tr '|' '\n')
309-
MESSAGE=$(printf "%s\n%s\n" "${MESSAGE}" "${BODY}")
351+
BODY=$(printf '%s' "${MESSAGE_BODY}" | sed 's/|/\n\n/g')
352+
MESSAGE=$(printf "%s\n\n%s\n" "${MESSAGE}" "${BODY}")
310353
fi
311354
312355
echo "::notice title=tag-message::Tagging all modules for ${NEXT_TAG}"
313356
314357
SIGNED=""
315358
if [[ '${{ inputs.enable-tag-signing }}' == 'true' ]] ; then
316359
SIGNED="-s"
360+
else
361+
# whenever not signed, we need a DCO
362+
git config --global user.name "bot-go-openapi"
363+
git config --global user.email "[email protected]"
317364
fi
318365
319366
# Tag all modules

.github/workflows/bump-release.yml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,15 @@ jobs:
114114
-
115115
name: Determine next tag
116116
id: bump-release
117-
uses: go-openapi/gh-actions/ci-jobs/next-tag@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
117+
uses: go-openapi/gh-actions/ci-jobs/next-tag@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
118118
with:
119119
bump-patch: ${{ steps.bump-check.outputs.bump-patch }}
120120
bump-minor: ${{ steps.bump-check.outputs.bump-minor }}
121121
bump-major: ${{ steps.bump-check.outputs.bump-major }}
122122
-
123123
name: Configure bot credentials
124124
if: ${{ inputs.enable-tag-signing == 'true' }}
125-
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
125+
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
126126
# This is using the GPG signature of bot-go-openapi.
127127
#
128128
# For go-openapi repos (using secrets: inherit):
@@ -144,18 +144,26 @@ jobs:
144144
MESSAGE_TITLE: ${{ inputs.tag-message-title }}
145145
MESSAGE_BODY: ${{ inputs.tag-message-body }}
146146
run: |
147-
# construct the tag message
147+
# Construct the tag message.
148+
# A blank line between title and body is required for git to
149+
# distinguish %(contents:subject) from %(contents:body).
150+
# Body lines use "|" as paragraph separator (workflow inputs
151+
# do not support multiline strings).
148152
set -x
149153
MESSAGE="${MESSAGE_TITLE}"
150154
if [[ -n "${MESSAGE_BODY}" ]] ; then
151-
BODY=$(echo "${MESSAGE_BODY}"|tr '|' '\n')
152-
MESSAGE=$(printf "%s\n%s\n" "${MESSAGE}" "${BODY}")
155+
BODY=$(printf '%s' "${MESSAGE_BODY}" | sed 's/|/\n\n/g')
156+
MESSAGE=$(printf "%s\n\n%s\n" "${MESSAGE}" "${BODY}")
153157
fi
154158
echo "::notice title=tag-message::${MESSAGE}"
155159
156160
SIGNED=""
157161
if [[ '${{ inputs.enable-tag-signing }}' == 'true' ]] ; then
158162
SIGNED="-s"
163+
else
164+
# whenever not signed, we need a DCO
165+
git config --global user.name "bot-go-openapi"
166+
git config --global user.email "[email protected]"
159167
fi
160168
161169
git tag "${SIGNED}" -m "${MESSAGE}" "${NEXT_TAG}"

.github/workflows/collect-reports.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
path: reports/
3333
-
3434
name: Install go-junit-report
35-
uses: go-openapi/gh-actions/install/go-junit-report@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
35+
uses: go-openapi/gh-actions/install/go-junit-report@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
3636
-
3737
name: Convert test reports to a merged JUnit XML
3838
# NOTE: codecov test reports only support JUnit format at this moment. See https://docs.codecov.com/docs/test-analytics.
@@ -57,7 +57,7 @@ jobs:
5757
verbose: true
5858
-
5959
name: Install go-ctrf-json-reporter
60-
uses: go-openapi/gh-actions/install/go-ctrf-json-reporter@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
60+
uses: go-openapi/gh-actions/install/go-ctrf-json-reporter@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
6161
-
6262
name: Convert test reports to CTRF JSON
6363
# description: |

.github/workflows/contributors.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
rm -rf contributors.json
8181
mv contributors.md CONTRIBUTORS.md
8282
- name: Configure bot credentials
83-
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
83+
uses: go-openapi/gh-actions/ci-jobs/bot-credentials@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
8484
id: bot-credentials
8585
# For go-openapi repos (using secrets: inherit):
8686
# Falls back to: CI_BOT_APP_ID, CI_BOT_APP_PRIVATE_KEY, CI_BOT_GPG_PRIVATE_KEY, etc.
@@ -145,7 +145,7 @@ jobs:
145145
- name: Auto-approve PR
146146
run: gh pr review --approve "$PR_URL"
147147
- name: Wait for all workflow runs to complete
148-
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
148+
uses: go-openapi/gh-actions/ci-jobs/wait-pending-jobs@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
149149
with:
150150
pr-url: ${{ env.PR_URL }}
151151
github-token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/go-test-monorepo.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
-
4343
name: Detect go mono-repo
4444
id: detect-monorepo
45-
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
45+
uses: go-openapi/gh-actions/ci-jobs/detect-go-monorepo@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
4646
-
4747
name: golangci-lint [monorepo]
4848
# golangci-action v9.1+ has an experimental built-in mono repo detection setup.
@@ -111,10 +111,10 @@ jobs:
111111
-
112112
name: Detect go version capabilities
113113
id: detect-go-version
114-
uses: go-openapi/gh-actions/ci-jobs/detect-go-version@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
114+
uses: go-openapi/gh-actions/ci-jobs/detect-go-version@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
115115
-
116116
name: Install gotestsum
117-
uses: go-openapi/gh-actions/install/gotestsum@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
117+
uses: go-openapi/gh-actions/install/gotestsum@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
118118
-
119119
name: Ensure TMP is created on windows runners
120120
# On windows, some tests require testing.TempDir to reside on the same drive as the code.

.github/workflows/go-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
cache: true
5959
-
6060
name: Install gotestsum
61-
uses: go-openapi/gh-actions/install/gotestsum@f7ed44020a2682556ac42fa9c210142495270354 # v1.4.5
61+
uses: go-openapi/gh-actions/install/gotestsum@f94d1f200adab8d24b37584e5f61795a6062421d # v1.4.6
6262
-
6363
name: Ensure TMP is created on windows runners
6464
# On windows, some tests require testing.TempDir to reside on the same drive as the code.

0 commit comments

Comments
 (0)