Skip to content

Commit 1c5fa78

Browse files
[FEATURE] Initial implementation of new CI-CHGLOG GHA (- WIP #155 -)
Additions with file .github/workflows/CI-CHGLOG.yml: * Initial implementation of new CHANGELOG generating action in CI/CD Changes in file docs/CI.md: * updated CI/CD documentation to mention new GHA CI-CHGLOG * updated 'How on-workflow_run triggers propagate' section with CI-CHGLOG * updated Key integrations section with CI-CHGLOG * updated Triggering CI/CD with CI-CHGLOG
1 parent 5c96987 commit 1c5fa78

File tree

2 files changed

+401
-4
lines changed

2 files changed

+401
-4
lines changed

.github/workflows/CI-CHGLOG.yml

Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
---
2+
name: CI-CHGLOG
3+
description: "Continuous Integration workflow for Generating the CHANGELOG.md file."
4+
run-name: Generate CHANGELOG.md
5+
#
6+
# This workflow runs after successful completion of CI-BUILD to ensure
7+
# that the codebase meets minimal acceptance criteria.
8+
#
9+
#
10+
# Triggers:
11+
# - Automatically on CI-BUILD workflow completion
12+
#
13+
# Required Secrets: None
14+
#
15+
# Dependencies:
16+
# - Requires successful completion of CI-BUILD workflow
17+
18+
on: # yamllint disable-line rule:truthy
19+
workflow_run:
20+
workflows: ["CI-BUILD"]
21+
types:
22+
- completed
23+
24+
# Declare default permissions as none.
25+
permissions: {}
26+
27+
jobs:
28+
check_build:
29+
permissions:
30+
actions: read
31+
pull-requests: read
32+
checks: write
33+
runs-on: ubuntu-latest
34+
env:
35+
GH_TOKEN: ${{ github.token }}
36+
outputs:
37+
should_run: ${{ steps.check.outputs.should_run }}
38+
sha: ${{ steps.load_build_info.outputs.build_sha }}
39+
branch_name: ${{ steps.get_env.outputs.branch }}
40+
parent_sha: ${{ steps.get_env.outputs.parent_sha }}
41+
branch_ref: ${{ steps.get_env.outputs.branch_ref }}
42+
trigger_id: ${{ steps.get_trigger_id.outputs.trigger_id }}
43+
build_id: ${{ steps.load_build_info.outputs.build_id }}
44+
build_url: ${{ steps.load_build_info.outputs.build_url }}
45+
build_ref: ${{ steps.load_build_info.outputs.build_ref }}
46+
build_ref_name: ${{ steps.load_build_info.outputs.build_ref_name }}
47+
build_sha: ${{ steps.load_build_info.outputs.build_sha }}
48+
build_artifact_filename: ${{ steps.load_build_info.outputs.build_artifact_filename }}
49+
build_artifact_url: ${{ steps.load_build_info.outputs.build_artifact_url }}
50+
build_artifact_id: ${{ steps.load_build_info.outputs.build_artifact_id }}
51+
build_artifact_digest: ${{ steps.load_build_info.outputs.build_artifact_digest }}
52+
build_environment: ${{ steps.load_build_info.outputs.build_environment }}
53+
chglog_url: ${{ steps.output_run_id.outputs.chglog_url }}
54+
chglog_id: ${{ steps.output_run_id.outputs.chglog_id }}
55+
check_id: ${{ steps.output_chglog_check_id.outputs.check-id }}
56+
steps:
57+
- id: check
58+
run: |
59+
if [[ "${{ github.event.workflow_run.conclusion }}" == "success" ]]; then
60+
echo "should_run=true" >> "$GITHUB_OUTPUT"
61+
else
62+
echo "should_run=false" >> "$GITHUB_OUTPUT"
63+
fi
64+
- id: get_trigger_id
65+
if: ${{ (steps.check.outputs.should_run == 'true') && success() }}
66+
run: |
67+
ID_VALUE=$(gh api "${{ github.event.workflow_run.url }}" --jq '.id')
68+
if [[ -n "$ID_VALUE" ]]; then
69+
echo "trigger_id=$ID_VALUE" >> "$GITHUB_OUTPUT"
70+
else
71+
echo "trigger_id=null" >> "$GITHUB_OUTPUT" # Default fallback
72+
fi
73+
- name: "Fetch Build Info"
74+
if: ${{ (github.repository == 'reactive-firewall/multicast') && success() }}
75+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
76+
with:
77+
path: "BUILD-info.txt"
78+
pattern: multicast-info-*
79+
repository: reactive-firewall/multicast
80+
merge-multiple: true
81+
github-token: ${{ env.GH_TOKEN }}
82+
run-id: ${{ steps.get_trigger_id.outputs.trigger_id }}
83+
- name: "move into place"
84+
id: load_build_info
85+
run: |
86+
mv -vf "BUILD-info.txt/BUILD-info.txt" ./"multicast-info.txt" ;
87+
wait ;
88+
rmdir -v ./"BUILD-info.txt"
89+
mv -vf ./"multicast-info.txt" ./BUILD-info.txt
90+
cat <"BUILD-info.txt" >> "$GITHUB_OUTPUT"
91+
if: ${{ (steps.check.outputs.should_run == 'true') && success() }}
92+
- id: output_run_id
93+
shell: bash
94+
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
95+
run: |
96+
printf "chglog_url=%s\n" 'https://github.com/reactive-firewall/multicast/actions/runs/${{ github.run_id }}' >> "$GITHUB_OUTPUT"
97+
printf "chglog_id=%s\n" ${{ github.run_id }} >> "$GITHUB_OUTPUT"
98+
- name: Checkout repository
99+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
100+
with:
101+
persist-credentials: false
102+
ref: ${{ steps.load_build_info.outputs.build_sha }}
103+
fetch-depth: 0
104+
- name: "Queue chglog GitHub Check"
105+
id: output_chglog_check_id
106+
uses: ./.github/actions/check-control
107+
with:
108+
name: "CI-CHGLOG"
109+
title: "Generating the CHANGELOG.md file"
110+
status: 'queued'
111+
summary: 'Will generate the CHANGELOG.md file'
112+
sha: ${{ steps.load_build_info.outputs.build_sha }}
113+
workflow-run-id: ${{ steps.output_run_id.outputs.chglog_id }}
114+
details-url: ${{ steps.output_run_id.outputs.chglog_url }}
115+
- name: Checkout target commit
116+
if: ${{ (steps.check.outputs.should_run == 'true') && success() }}
117+
run: git checkout ${{ steps.load_build_info.outputs.build_sha }}
118+
- id: get_env
119+
if: ${{ (steps.check.outputs.should_run == 'true') && success() }}
120+
run: |
121+
echo "branch=$(git name-rev --name-only $(git log -1 --format=%H) | cut -d~ -f1-1)" >> "$GITHUB_OUTPUT"
122+
echo "parent_sha=$(git merge-base $(git log -1 --format=%H) refs/remotes/origin/stable)" >> "$GITHUB_OUTPUT"
123+
BRANCH_REF=$(head -n1 <(git symbolic-ref HEAD 2>/dev/null || git show-ref $(git name-rev --name-only $(git log -1 --format=%H)) | cut -d\ -f2-2) ) ;
124+
echo "branch_ref=${BRANCH_REF}" >> "$GITHUB_OUTPUT"
125+
- name: "Start chglog GitHub Check"
126+
id: start_chglog_success
127+
if: ${{ (steps.check.outputs.should_run == 'true') && success() && (github.repository == 'reactive-firewall/multicast') }}
128+
uses: ./.github/actions/check-control
129+
with:
130+
name: "CI-CHGLOG"
131+
check-id: ${{ steps.output_chglog_check_id.outputs.check-id }}
132+
title: "Generating the CHANGELOG.md file"
133+
status: 'in_progress'
134+
summary: 'Generating the CHANGELOG.md file is _progress_'
135+
sha: ${{ steps.load_build_info.outputs.build_sha }}
136+
workflow-run-id: ${{ steps.output_run_id.outputs.chglog_id }}
137+
details-url: ${{ steps.output_run_id.outputs.chglog_url }}
138+
139+
CHGLOG:
140+
permissions:
141+
actions: read
142+
contents: read
143+
pull-requests: read
144+
statuses: write
145+
needs: check_build
146+
if: ${{ !cancelled() && (needs.check_build.outputs.should_run == 'true') }}
147+
runs-on: ubuntu-latest
148+
environment: ${{ needs.check_build.outputs.build_environment }}
149+
defaults:
150+
run:
151+
shell: bash
152+
timeout-minutes: 15
153+
outputs:
154+
chglog_status: ${{ steps.gen_changelog.outcome || 'cancelled' }}
155+
artifact-id: ${{ steps.upload.outputs.artifact-id }}
156+
artifact-name: 'multicast-chglog-${{ needs.check_build.outputs.sha }}'
157+
artifact-url: ${{ steps.upload.outputs.artifact-url }}
158+
artifact-digest: ${{ steps.upload.outputs.artifact-digest }}
159+
env:
160+
PYTHON_VERSION: "${{ vars.PYTHON_DEFAULT }}"
161+
CHGLOG_PATH: '${{ github.workspace }}/CHANGELOG.md'
162+
LANG: "en_US.utf-8"
163+
steps:
164+
- name: pre-checkout repository for actions
165+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
166+
with:
167+
persist-credentials: false
168+
ref: ${{ needs.check_build.outputs.sha }}
169+
sparse-checkout: '.github/actions/checkout-and-rebuild'
170+
- name: Checkout repository for chglog with ${{ matrix.python-version }}
171+
id: fetch-build
172+
uses: ./.github/actions/checkout-and-rebuild
173+
with:
174+
sha: ${{ needs.check_build.outputs.sha }}
175+
build-run-id: ${{ needs.check_build.outputs.trigger_id }}
176+
python-version: ${{ matrix.python-version }}
177+
path: ${{ github.workspace }}
178+
- name: "Generate CHANGELOG for ${{ needs.check_build.outputs.sha }}...${{ needs.check_build.outputs.parent_sha }}"
179+
id: gen_changelog
180+
env:
181+
CHGLOG_RANGE: '${{ needs.check_build.outputs.sha }}...${{ needs.check_build.outputs.parent_sha }}'
182+
CHGLOG_TOOL: '${{ github.workspace }}/generate_changelog.sh'
183+
run: |
184+
"${CHGLOG_TOOL}" "${CHGLOG_RANGE}" >"${CHGLOG_PATH}" || exit 1;
185+
- name: Upload CHANGELOG artifact
186+
id: upload
187+
if: ${{ success() && (github.repository == 'reactive-firewall/multicast') }}
188+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
189+
with:
190+
path: CHANGELOG.md
191+
name: 'multicast-chglog-${{ needs.check_build.outputs.sha }}'
192+
compression-level: 9
193+
overwrite: true
194+
195+
CHGLOG_SUMMARY:
196+
permissions:
197+
actions: read
198+
pull-requests: read
199+
checks: write
200+
needs: [check_build, CHGLOG]
201+
runs-on: ubuntu-latest
202+
if: ${{ !cancelled() && (needs.check_build.outputs.should_run == 'true') && (needs.CHGLOG.outputs.chglog_status != 'cancelled') }}
203+
timeout-minutes: 3
204+
outputs:
205+
chglog_success: ${{ steps.report_status.outputs.chglog_success }}
206+
chglog_sha: ${{ needs.check_build.outputs.sha }}
207+
build_success: ${{ steps.report_status.outputs.build_success }}
208+
build_trigger_id: ${{ needs.check_build.outputs.trigger_id }}
209+
build_sha: ${{ needs.check_build.outputs.sha }}
210+
steps:
211+
- name: Download ChangeLog Artifact
212+
id: download
213+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
214+
with:
215+
path: '${{ runner.temp }}/multicast-chglog-${{ needs.check_build.outputs.sha }}'
216+
artifact-ids: ${{ needs.CHGLOG.outputs.artifact-id }}
217+
repository: reactive-firewall/multicast
218+
- name: "Move chglog into place"
219+
id: load_chglog_info
220+
if: ${{ always() }}
221+
run: |
222+
mv -vf "${{ runner.temp }}/multicast-chglog-${{ needs.check_build.outputs.sha }}"/CHANGELOG.md" "${{ github.workspace }}/CHANGELOG.md" ;
223+
wait ;
224+
rmdir -v "${{ runner.temp }}/multicast-chglog-${{ needs.check_build.outputs.sha }}" || : ; # remove if able
225+
- name: "Report chglog status"
226+
id: report_status
227+
env:
228+
BUILD_SHA: ${{ needs.check_build.outputs.build_sha }}
229+
CHGLOG_ID: ${{ needs.check_build.outputs.chglog_id }}
230+
CHGLOG_COMMENT_BODY: '${{ github.workspace }}/chglog-Summary-Artifact.txt'
231+
CHGLOG_ARTIFACT_NAME: ${{ needs.CHGLOG.outputs.artifact-name }}
232+
CHGLOG_ARTIFACT_URL: ${{ needs.CHGLOG.outputs.artifact-url }}
233+
run: |
234+
if [[ "${{ needs.chglog.outputs.chglog_status }}" == "success" ]]; then
235+
printf "%s\n\n" "# :page_facing_up: Changelog Summary" > "${CHGLOG_COMMENT_BODY}"
236+
printf "%s\n" " * :ballot_box_with_check: Generating Changelog \`${CHGLOG_ID}\` succeeded with commit [${BUILD_SHA}](https://github.com/reactive-firewall/multicast/commit/${BUILD_SHA})" >> "${CHGLOG_COMMENT_BODY}"
237+
printf "%s\n" "chglog_success=true" >> "$GITHUB_OUTPUT"
238+
printf "%s\n" "chglog_summary=Generating Changelog Passed" >> "$GITHUB_OUTPUT"
239+
else
240+
printf "%s\n\n" "# Known flaws." > "${CHGLOG_COMMENT_BODY}"
241+
printf "%s\n" "> [!WARNING]" >> "${CHGLOG_COMMENT_BODY}"
242+
printf "%s\n\n" "> This commit has known flaws. Each commit is subject to minimal acceptance testing, and then select commits are subject to extra testing to evaluate release candidates; This commit has been deemed _not ready_ for release." >> "${CHGLOG_COMMENT_BODY}"
243+
printf "%s\n" "chglog_success=false" >> "$GITHUB_OUTPUT"
244+
printf "%s\n" " * :x: Generating Changelog \`${CHGLOG_ID}\` Failed" >> "${CHGLOG_COMMENT_BODY}"
245+
printf "%s\n" "chglog_summary=Generating Changelog Unsuccessful" >> "$GITHUB_OUTPUT"
246+
fi
247+
if [[ ( -r "CHANGELOG.md" ) ]] ; then
248+
printf "%s\n" " * :page_facing_up: Including generating the file \`CHANGELOG.md\`" >> "${CHGLOG_COMMENT_BODY}"
249+
printf "%s\n" " * :package: successfully producing the artifact [${CHGLOG_ARTIFACT_NAME}](${CHGLOG_ARTIFACT_URL})" >> "${CHGLOG_COMMENT_BODY}"
250+
else
251+
printf "%s\n" " * :x: Failing to generate the file \`CHANGELOG.md\`" >> "${CHGLOG_COMMENT_BODY}"
252+
fi
253+
cat <"${CHGLOG_COMMENT_BODY}" >> "$GITHUB_STEP_SUMMARY"
254+
{ printf "%s\n" 'chglog_text<<EOF'; cat <"${CHGLOG_COMMENT_BODY}"; printf "%s\n" 'EOF'; } >> "$GITHUB_OUTPUT"
255+
- name: "Upload chglog summary"
256+
id: upload-chglog-summary
257+
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
258+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
259+
with:
260+
path: ./chglog-Summary-Artifact.txt
261+
name: chglog-COMMENT-BODY-${{ needs.check_build.outputs.sha }}
262+
if-no-files-found: error
263+
compression-level: 3
264+
retention-days: 2
265+
overwrite: true
266+
- name: Checkout repository actions for check
267+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
268+
with:
269+
persist-credentials: false
270+
ref: ${{ needs.check_build.outputs.sha }}
271+
sparse-checkout: '.github/actions/check-control'
272+
- name: "Compleate chglog GitHub Check"
273+
id: compleate_chglog
274+
if: ${{ (github.repository == 'reactive-firewall/multicast') && always() }}
275+
uses: ./.github/actions/check-control
276+
with:
277+
name: "CI-CHGLOG"
278+
check-id: ${{ needs.check_build.outputs.check_id }}
279+
title: "Generating the CHANGELOG.md file"
280+
status: 'completed'
281+
conclusion: ${{ needs.CHGLOG.outputs.chglog_status }}
282+
summary: ${{ steps.report_status.outputs.chglog_summary }}
283+
text: ${{ steps.report_status.outputs.chglog_text }}
284+
sha: ${{ needs.check_build.outputs.sha }}
285+
workflow-run-id: ${{ needs.check_build.outputs.chglog_id }}
286+
details-url: ${{ needs.check_build.outputs.chglog_url }}
287+
288+
CHGLOG_STATUS:
289+
permissions:
290+
actions: read
291+
pull-requests: read
292+
needs: [check_build, CHGLOG]
293+
runs-on: ubuntu-latest
294+
if: ${{ !cancelled() && (needs.check_build.outputs.should_run == 'true') && (needs.CHGLOG.outputs.chglog_status != 'cancelled') }}
295+
timeout-minutes: 2
296+
outputs:
297+
chglog_success: ${{ steps.check_status.outputs.chglog_success }}
298+
chglog_sha: ${{ needs.check_build.outputs.sha }}
299+
build_success: ${{ steps.check_status.outputs.build_success }}
300+
build_trigger_id: ${{ needs.check_build.outputs.trigger_id }}
301+
build_sha: ${{ needs.check_build.outputs.sha }}
302+
steps:
303+
- id: check_status
304+
run: |
305+
if [[ "${{ needs.check_build.result }}" == "success" ]]; then
306+
printf "%s\n" "build_success=${{ needs.check_build.outputs.should_run }}" >> "$GITHUB_OUTPUT"
307+
printf "%s\n" "parent_sha=${{ needs.check_build.outputs.parent_sha }}" >> "$GITHUB_OUTPUT"
308+
printf "%s\n" "build_url=${{ needs.check_build.outputs.build_url }}" >> "$GITHUB_OUTPUT"
309+
printf "%s\n" "build_ref=${{ needs.check_build.outputs.build_ref }}" >> "$GITHUB_OUTPUT"
310+
printf "%s\n" "build_sha=${{ needs.check_build.outputs.build_sha }}" >> "$GITHUB_OUTPUT"
311+
printf "%s\n" "build_ref_name=${{ needs.check_build.outputs.build_ref_name }}" >> "$GITHUB_OUTPUT"
312+
printf "%s\n" "build_artifact_filename=${{ needs.check_build.outputs.build_artifact_filename }}" >> "$GITHUB_OUTPUT"
313+
printf "%s\n" "build_artifact_url=${{ needs.check_build.outputs.build_artifact_url }}" >> "$GITHUB_OUTPUT"
314+
printf "%s\n" "build_artifact_id=${{ needs.check_build.outputs.build_artifact_id }}" >> "$GITHUB_OUTPUT"
315+
printf "%s\n" "build_artifact_digest=${{ needs.check_build.outputs.build_artifact_digest }}" >> "$GITHUB_OUTPUT"
316+
printf "%s\n" "build_environment=${{ needs.check_build.outputs.build_environment }}" >> "$GITHUB_OUTPUT"
317+
printf "%s\n" "build_id=${{ needs.check_build.outputs.build_id }}" >> "$GITHUB_OUTPUT"
318+
cat <"$GITHUB_OUTPUT" >> "BUILD-info.txt"
319+
else
320+
printf "%s\n" "build_success=false" >> "$GITHUB_OUTPUT"
321+
fi
322+
if [[ "${{ needs.chglog.result }}" == "success" && "${{ needs.check_build.result }}" == "success" ]]; then
323+
printf "%s\n" "chglog_success=true" >> "$GITHUB_OUTPUT"
324+
printf "%s\n" "chglog_url=${{ github.api_url }}" >> "$GITHUB_OUTPUT"
325+
printf "%s\n" "chglog_ref=${{ needs.check_build.outputs.build_ref }}" >> "$GITHUB_OUTPUT"
326+
printf "%s\n" "chglog_sha=${{ needs.check_build.outputs.sha }}" >> "$GITHUB_OUTPUT"
327+
printf "%s\n" "chglog_parent_sha=${{ needs.check_build.outputs.parent_sha }}" >> "$GITHUB_OUTPUT"
328+
printf "%s\n" "chglog_ref_name=${{ needs.check_build.outputs.branch_ref }}" >> "$GITHUB_OUTPUT"
329+
printf "%s\n" "chglog_environment=${{ needs.check_build.outputs.build_environment }}" >> "$GITHUB_OUTPUT"
330+
printf "%s\n" "chglog_id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
331+
else
332+
printf "%s\n" "chglog_success=false" >> "$GITHUB_OUTPUT"
333+
fi
334+
cat <"$GITHUB_OUTPUT" >> "chglog-info.txt"
335+
- name: Upload build summary
336+
id: upload-build-info
337+
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
338+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
339+
with:
340+
path: "chglog-info.txt"
341+
name: multicast-chglog-info-${{ needs.check_build.outputs.sha }}
342+
if-no-files-found: error
343+
compression-level: 3
344+
retention-days: 2
345+
overwrite: true
346+
347+
chglog_REPORT:
348+
permissions:
349+
actions: read
350+
contents: write
351+
needs: [check_build, CHGLOG_SUMMARY]
352+
runs-on: ubuntu-latest
353+
if: ${{ !cancelled() }}
354+
steps:
355+
- name: "Download Status Summary Artifact"
356+
id: download-chglog-summary
357+
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
358+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
359+
with:
360+
name: chglog-COMMENT-BODY-${{ needs.check_build.outputs.sha }}
361+
github-token: ${{ github.token }}
362+
- name: "chglog commit comment"
363+
id: chglog-commit-comment
364+
if: ${{ success() && (github.repository == 'reactive-firewall/multicast') }}
365+
uses: peter-evans/commit-comment@5a6f8285b8f2e8376e41fe1b563db48e6cf78c09 # v3.0.0
366+
with:
367+
sha: ${{ needs.check_build.outputs.sha }}
368+
token: ${{ github.token }}
369+
body-path: '${{ steps.download-chglog-summary.outputs.download-path }}/chglog-Summary-Artifact.txt'

0 commit comments

Comments
 (0)