Skip to content

Build patch-FAQ-425 #591

Build patch-FAQ-425

Build patch-FAQ-425 #591

Workflow file for this run

---
name: CI-BUILD
description: "Continuous Integration workflow for building, the project."
run-name: Build ${{ github.ref_name }}
#
# Jobs included:
# - BUILD: Ensures the project compiles correctly
# - BOOTSTRAP: Tests installation across Python versions and locales
#
# Required Secrets:
# NONE
on: # yamllint disable-line rule:truthy
push:
branches: ["**"] # matches any branch
tags: ["v*"]
# Declare default permissions as none.
permissions: {}
env:
ENVIRONMENT: ${{ (github.ref == 'refs/heads/stable' || startsWith(github.ref, 'refs/tags/v')) && 'Deployment' || (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/feature') || startsWith(github.ref, 'refs/heads/patch-') || startsWith(github.ref, 'refs/tags/v')) && 'Testing' || 'Experimenting' }}
# Define Python versions at the top level -- Expected format: X.Y (e.g., 3.13)
PYTHON_DEFAULT: "${{ vars.PYTHON_DEFAULT }}"
PYTHON_OLD_MIN: "${{ vars.PYTHON_OLD_MIN }}" # For Oldest Python versions
PYTHON_EXPERIMENTAL: "${{ vars.PYTHON_EXPERIMENTAL }}" # For future Python versions
jobs:
BUILD:
permissions:
actions: read
contents: read
statuses: write
packages: none
pull-requests: read
security-events: none
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
runs-on: ubuntu-latest
environment: ${{ (github.ref == 'refs/heads/stable' || startsWith(github.ref, 'refs/tags/v')) && 'Deployment' || (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/heads/feature') || startsWith(github.ref, 'refs/heads/patch-') || startsWith(github.ref, 'refs/tags/v')) && 'Testing' || 'Experimenting' }}
defaults:
run:
shell: bash
env:
LANG: "en_US.UTF-8"
BUILD_MATCH_PATTERN: "${{ vars.BUILD_MATCH_PATTERN }}"
outputs:
build_status: ${{ steps.build.outcome }}
artifact-id: ${{ steps.upload.outputs.artifact-id }}
artifact-url: ${{ steps.upload.outputs.artifact-url }}
artifact-digest: ${{ steps.upload.outputs.artifact-digest }}
artifact-files: ${{ steps.buildfiles.outputs.files }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- id: build-python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "${{ vars.PYTHON_DEFAULT }}"
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Pre-Clean
id: clean
run: make -j1 -f Makefile purge 2>/dev/null || true
- name: "License"
id: show-build-license
shell: bash
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
run: |
if [[ -r LICENSE.md ]] ; then
printf "\n\n"
cat <LICENSE.md ;
printf "\n\n"
else
printf "%s\n" "::warning title=UNLICENSED:: This is an UNLICENSED Build"
fi
- name: Test Build
id: build
run: make -j1 -f Makefile build
- name: Get BUILD Files
id: buildfiles
shell: bash
run: |
FILES=$(git ls-files -oi --exclude-standard -- ${{ env.BUILD_MATCH_PATTERN }} )
if [ -z "$FILES" ]; then
printf "%s\n" "::warning file=.github/workflows/CI-BUILD.yml:: No Built files found."
printf "%s\n" "files=" >> "$GITHUB_OUTPUT"
else
printf "%s\n" "Built files found:"
printf "%s\n" "$FILES"
# Replace line breaks with commas for GitHub Action Output
FILES="${FILES//$'\n'/ }"
printf "%s\n" "files=$FILES" >> "$GITHUB_OUTPUT"
fi
if: ${{ success() }}
- name: "Hint for pip hashing"
id: build-pip-hash-hint
shell: bash
if: ${{ !cancelled() }}
run: |
for build_file in ${{ steps.buildfiles.outputs.files }} ; do
${{ steps.build-python.outputs.python-path }} -m pip hash --algorithm sha512 ${build_file} ;
done
- name: Upload build artifact
id: upload
if: ${{ !cancelled() && (steps.buildfiles.outputs.files != '') && (github.repository == 'reactive-firewall/multicast') }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: dist
name: multicast-build-${{ github.sha }}
compression-level: 3
overwrite: true
BOOTSTRAP:
permissions:
actions: read
contents: read
statuses: write
packages: none
pull-requests: read
security-events: none
if: ${{ (github.repository == 'reactive-firewall/multicast') && !cancelled() }}
needs: BUILD
runs-on: ubuntu-latest
defaults:
run:
shell: bash
timeout-minutes: 5
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
python-version: ["${{ vars.PYTHON_OLD_MIN }}", "${{ vars.PYTHON_DEFAULT }}", "${{ vars.PYTHON_EXPERIMENTAL }}"]
lang-var: ["de.utf-8", "jp.utf-8"]
experimental: [true]
include:
- python-version: "${{ vars.PYTHON_DEFAULT }}"
lang-var: "de.utf-8"
experimental: false
- python-version: "${{ vars.PYTHON_DEFAULT }}"
lang-var: "jp.utf-8"
experimental: false
- python-version: "${{ vars.PYTHON_OLD_MIN }}"
lang-var: "en_US.utf-8"
experimental: false
- python-version: "${{ vars.PYTHON_OLD_EXTRA }}"
lang-var: "en_US.utf-8"
experimental: false
- python-version: "${{ vars.PYTHON_DEFAULT }}"
lang-var: "en_US.utf-8"
experimental: false
- python-version: "${{ vars.PYTHON_EXPERIMENTAL }}"
lang-var: "en_US.utf-8"
experimental: ${{ (needs.BUILD.environment == 'Experimenting') }}
outputs:
bootstrap_status: ${{ steps.bootstrap.outcome }}
env:
PYTHON_VERSION: ${{ matrix.python-version }}
LANG: ${{ matrix.lang-var }}
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}
- name: Pre-build
id: bootstrap
run: |
printf "%s\n" "::group::make-init"
make -f Makefile init || exit 1
printf "%s\n%s\n" "::endgroup::" "::group::make-clean"
make -j1 -f Makefile clean || true ;
printf "%s\n%s\n" "::endgroup::" "::group::make-build"
make -j1 -f Makefile build || exit 1 ;
printf "%s\n" "::endgroup::"
shell: bash
- name: Summerize Building
id: sumerize-py-build
run: |
printf "%s\n" "- [x] Building works on python version ${{ matrix.python-version }}" >> "$GITHUB_STEP_SUMMARY"
if: ${{ success() }}
shell: bash
- name: Run Tests
id: test-user-install
run: make -j1 -f Makefile user-install ;
shell: bash
- name: Summerize Install
id: sumerize-user-install
run: |
printf "%s\n" "- [x] User Installing works on python version ${{ matrix.python-version }}" >> "$GITHUB_STEP_SUMMARY"
if: ${{ success() }}
shell: bash
- name: Test Info
id: test-info
run: python -m multicast --version || true ;
- name: Post-Clean
id: post-bootstrap
run: |
make -j1 -f Makefile purge || true ;
make -j1 -f Makefile clean || true ;
if: ${{ always() }}
shell: bash
BUILD_ATTEST:
permissions:
actions: read
id-token: write
contents: read
attestations: write
needs: [BUILD]
runs-on: ubuntu-latest
environment: ${{ needs.BUILD.envs.ENVIRONMENT }}
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
outputs:
build-artifact-attestation-url: ${{ steps.multicast-build-attest.outputs.attestation-url }}
build-artifact-attestation-id: ${{ steps.multicast-build-attest.outputs.attestation-id }}
steps:
- name: Download All Artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: ${{ github.workspace }}/dist
pattern: multicast-build-${{ github.sha }}
merge-multiple: true
- name: Calculate artifact digests
run: |
shasum -a 512 dist/* > build.checksums.txt
- name: "Attest Build Checksums"
id: multicast-build-chksum-attest
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') && (needs.BUILD.envs.ENVIRONMENT == 'Deployment' && startsWith(github.ref, 'refs/tags/v')) }}
uses: actions/attest-build-provenance@39cb715ce0ddd23df1f705e863f642bfb72dfb2b # v2.3.0
with:
subject-checksums: build.checksums.txt
github-token: ${{ github.token }}
- name: "Attest Build Artifact"
id: multicast-build-attest
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
uses: actions/attest-build-provenance@39cb715ce0ddd23df1f705e863f642bfb72dfb2b # v2.3.0
with:
subject-name: multicast-build-${{ github.sha }}
subject-digest: sha256:${{ needs.BUILD.outputs.artifact-digest }}
github-token: ${{ github.token }}
show-summary: false
BUILD_STATUS:
permissions:
actions: read
contents: read
pull-requests: read
needs: [BUILD, BOOTSTRAP, BUILD_ATTEST]
runs-on: ubuntu-latest
environment: ${{ needs.BUILD.envs.ENVIRONMENT }}
if: ${{ !cancelled() }}
outputs:
didBUILD: ${{ steps.check_status.outputs.build_success }}
build_ref: ${{ steps.check_status.outputs.build_ref }}
build_ref_name: ${{ steps.check_status.outputs.build_ref_name }}
build-artifact-filename: ${{ steps.check_status.outputs.build_artifact_filename }}
build-artifact-id: ${{ needs.BUILD.outputs.artifact-id }}
build-artifact-url: ${{ needs.BUILD.outputs.artifact-url }}
build-artifact-digest: ${{ needs.BUILD.outputs.artifact-digest }}
build-artifact-attestation-url: ${{ needs.BUILD_ATTEST.outputs.build-artifact-attestation-url || '' }}
build-artifact-attestation-id: ${{ needs.BUILD_ATTEST.outputs.build-artifact-attestation-id || '' }}
environment: ${{ steps.check_status.outputs.build_environment }}
steps:
- id: check_status
run: |
if [[ "${{ needs.BUILD.result }}" == "success" && "${{ needs.BOOTSTRAP.result }}" == "success" ]]; then
printf "%s\n" "build_success=true" >> "$GITHUB_OUTPUT"
else
printf "%s\n" "build_success=false" >> "$GITHUB_OUTPUT"
fi
printf "%s\n" "build_url=${{ github.api_url }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_ref=${{ github.ref }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_sha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_ref_name=${{ github.ref_name }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_artifact_filename=multicast-build-${{ github.sha }}.zip" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_artifact_url=${{ needs.BUILD.outputs.artifact-url }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_artifact_id=${{ needs.BUILD.outputs.artifact-id }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_artifact_digest=${{ needs.BUILD.outputs.artifact-digest }}" >> "$GITHUB_OUTPUT"
if [[ "${{ needs.BUILD_ATTEST.result }}" == "success" ]] ; then
printf "%s\n" "build-artifact-attestation-url=${{ needs.BUILD_ATTEST.outputs.build-artifact-attestation-url }}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build-artifact-attestation-id=${{ needs.BUILD_ATTEST.outputs.build-artifact-attestation-id }}" >> "$GITHUB_OUTPUT"
fi
printf "%s\n" "build_environment=${ENVIRONMENT}" >> "$GITHUB_OUTPUT"
printf "%s\n" "build_id=${{ github.run_id }}" >> "$GITHUB_OUTPUT"
cat <"$GITHUB_OUTPUT" >> "BUILD-info.txt"
- name: Download All Artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: ${{ github.workspace }}/dist
pattern: multicast-build-${{ github.sha }}
merge-multiple: true
- name: Upload build summary
id: upload-build-info
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: "BUILD-info.txt"
name: multicast-info-${{ github.sha }}
if-no-files-found: error
compression-level: 3
retention-days: 2
overwrite: true
- name: "Summarize Build"
id: summarize-build-success
env:
BUILD_ID: ${{ github.run_id }}
BUILD_SHA: ${{ github.sha }}
BUILD_ARTIFACT_FILES: ${{ needs.BUILD.outputs.artifact-files }}
BUILD_COMMENT_BODY: '${{ github.workspace }}/Build-Summary-Artifact.txt'
shell: bash
run: |
printf "%s\n\n" "# :building_construction: Build" > "${BUILD_COMMENT_BODY}"
printf "%s\n" ":ballot_box_with_check: BUILD \`${BUILD_ID}\` succeeded with commit [${BUILD_SHA}](https://github.com/reactive-firewall/multicast/commit/${BUILD_SHA})" >> "${BUILD_COMMENT_BODY}"
if [[ ( -d dist ) ]] ; then
for BLD_FILE in ${BUILD_ARTIFACT_FILES} ; do
printf "%s\n" " * :page_facing_up: Including building the file \`${BLD_FILE}\`" >> "${BUILD_COMMENT_BODY}"
done
printf "%s\n" " * :package: Including producing the build artifact [multicast-build-${BUILD_SHA}](https://github.com/reactive-firewall/multicast/actions/runs/${BUILD_ID}#artifacts)" >> "${BUILD_COMMENT_BODY}"
if [[ "${{ needs.BUILD_ATTEST.result }}" == "success" ]] ; then
printf "%s\n" " * :receipt: Build Attestation Created [\`${{ needs.BUILD_ATTEST.outputs.build-artifact-attestation-id }}\`](${{ needs.BUILD_ATTEST.outputs.build-artifact-attestation-url }})" >> "${BUILD_COMMENT_BODY}"
else
printf "%s\n" " * :no_entry_sign: Build Unattested" >> "${BUILD_COMMENT_BODY}"
fi
fi
cat <"${BUILD_COMMENT_BODY}" >> "$GITHUB_STEP_SUMMARY"
if: ${{ success() && (github.repository == 'reactive-firewall/multicast') }}
- name: "Summarize Build (FAILED)"
id: summarize-build-failure
env:
BUILD_ID: ${{ github.run_id }}
BUILD_SHA: ${{ github.sha }}
BUILD_COMMENT_BODY: '${{ github.workspace }}/Build-Summary-Artifact.txt'
shell: bash
run: |
printf "%s\n" "# :construction: Build" > "${BUILD_COMMENT_BODY}"
printf "%s\n" ":x: ~BUILD \`${BUILD_ID}\` succeeded with commit [${BUILD_SHA}](https://github.com/reactive-firewall/multicast/commit/${BUILD_SHA})~" > "${BUILD_COMMENT_BODY}"
cat <"${BUILD_COMMENT_BODY}" >> "$GITHUB_STEP_SUMMARY"
if: ${{ failure() && (github.repository == 'reactive-firewall/multicast') }}
- name: Upload build summary
id: upload-build-summary
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
path: ./Build-Summary-Artifact.txt
name: BUILD-COMMENT-BODY-${{ github.sha }}
if-no-files-found: error
compression-level: 3
retention-days: 2
overwrite: true
BUILD_SUMMARY:
permissions:
actions: read
contents: write
needs: [BUILD_STATUS]
runs-on: ubuntu-latest
environment: ${{ needs.BUILD_STATUS.outputs.environment }}
if: ${{ !cancelled() }}
steps:
- name: "Download Status Summary Artifact"
id: download-build-summary
if: ${{ !cancelled() && (github.repository == 'reactive-firewall/multicast') }}
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: BUILD-COMMENT-BODY-${{ github.sha }}
github-token: ${{ github.token }}
- name: "Build commit comment"
id: build-commit-comment
if: ${{ success() && (github.repository == 'reactive-firewall/multicast') }}
uses: peter-evans/commit-comment@5a6f8285b8f2e8376e41fe1b563db48e6cf78c09 # v3.0.0
with:
sha: ${{ github.sha }}
token: ${{ github.token }}
body-path: '${{ steps.download-build-summary.outputs.download-path }}/Build-Summary-Artifact.txt'