Skip to content

🔑 Generate PQCA CBOM #58

🔑 Generate PQCA CBOM

🔑 Generate PQCA CBOM #58

---
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: 2025 The Linux Foundation
name: '🔑 Generate PQCA CBOM'
on:
push:
branches:
- master
workflow_dispatch:
inputs:
GERRIT_BRANCH:
description: "Branch that change is against"
required: false
type: string
GERRIT_CHANGE_ID:
description: "The ID for the change"
required: false
type: string
GERRIT_CHANGE_NUMBER:
description: "The Gerrit number"
required: false
type: string
GERRIT_CHANGE_URL:
description: "URL to the change"
required: false
type: string
GERRIT_EVENT_TYPE:
description: "Type of Gerrit event"
required: false
type: string
GERRIT_PATCHSET_NUMBER:
description: "The patch number for the change"
required: false
type: string
GERRIT_PATCHSET_REVISION:
description: "The revision sha"
required: false
type: string
GERRIT_PROJECT:
description: "Project in Gerrit"
required: false
type: string
GERRIT_REFSPEC:
description: "Gerrit refspec of change"
required: false
type: string
GERRIT_DISABLED:
description: "Run without Gerrit components"
required: false
default: false
type: boolean
permissions: {}
concurrency:
group: "gerrit-merge-cbom-${{ github.workflow }}-${{ github.event.inputs.GERRIT_CHANGE_ID || github.run_id }}"
cancel-in-progress: true
jobs:
notify:
if: github.event_name == 'workflow_dispatch' && inputs.GERRIT_DISABLED != true
runs-on: ubuntu-latest
steps:
# Harden the runner used by this workflow
# yamllint disable-line rule:line-length
- uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
with:
egress-policy: audit
- name: Notify job start
# yamllint disable-line rule:line-length
uses: lfreleng-actions/gerrit-review-action@91db81bb09f604bb620810640c045eeb1f6a9e54 # v1.1.0
with:
host: ${{ vars.GERRIT_SERVER }}
username: ${{ vars.GERRIT_SSH_USER }}
key: ${{ secrets.GERRIT_SSH_PRIVKEY }}
known_hosts: ${{ vars.GERRIT_KNOWN_HOSTS }}
gerrit-change-number: ${{ inputs.GERRIT_CHANGE_NUMBER }}
gerrit-patchset-number: ${{ inputs.GERRIT_PATCHSET_NUMBER }}
vote-type: clear
- name: Allow replication
run: sleep 10s
cbom-create:
name: 'Generate PQCA CBOM'
runs-on: ubuntu-latest
if: always()
needs: [notify]
permissions:
contents: write
pull-requests: write
timeout-minutes: 45 # Set this timeout value as needed
steps:
# Harden the runner used by this workflow
# yamllint disable-line rule:line-length
- uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
with:
egress-policy: audit
# Allow time for Gerrit-to-GitHub mirror replication on push
- name: 'Wait for mirror replication'
if: github.event_name == 'push'
run: sleep 10s
# Standard checkout for push events or manual runs without Gerrit
- name: 'Checkout repository'
# yamllint disable-line rule:line-length
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.GERRIT_DISABLED == true)
# yamllint disable-line rule:line-length
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Gerrit-aware checkout for workflow_dispatch with Gerrit context
- name: 'Checkout Gerrit change'
# yamllint disable-line rule:line-length
if: github.event_name == 'workflow_dispatch' && inputs.GERRIT_DISABLED != true
# yamllint disable-line rule:line-length
uses: lfreleng-actions/checkout-gerrit-change-action@8523d768952d9690702b4696a8310d2a84b1be39 # v1.0.1
with:
gerrit-refspec: ${{ inputs.GERRIT_REFSPEC }}
gerrit-project: ${{ inputs.GERRIT_PROJECT }}
gerrit-url: ${{ vars.GERRIT_URL }}
delay: "0s"
- name: 'Find Python projects'
id: find-python
run: |
# Find all directories containing setup.py or pyproject.toml
PYTHON_DIRS=()
while IFS= read -r file; do
if [ -n "$file" ]; then
dir=$(dirname "$file" | sed 's|^\./||')
PYTHON_DIRS+=("$dir")
fi
done < <(find . -type f \( -name "setup.py" -o -name "pyproject.toml" \))
echo "Found ${#PYTHON_DIRS[@]} Python project(s)"
if [ ${#PYTHON_DIRS[@]} -gt 0 ]; then
echo "has-python=true" >> "$GITHUB_OUTPUT"
echo "Python projects found in:"
printf '%s\n' "${PYTHON_DIRS[@]}"
# Save directories for iteration
printf '%s\n' "${PYTHON_DIRS[@]}" > /tmp/python_dirs.txt
echo "DEBUG: has-python output set to: true"
else
echo "has-python=false" >> "$GITHUB_OUTPUT"
echo "No Python projects found"
echo "DEBUG: has-python output set to: false"
fi
- name: 'Check for pom.xml'
id: check-pom-xml
# yamllint disable-line rule:line-length
uses: lfreleng-actions/path-check-action@9606e61c870025bc956e63156d1d55c5df54426c # v0.2.0
with:
path: 'pom.xml'
- name: 'Build Python projects'
id: python-build
if: steps.find-python.outputs.has-python == 'true'
run: |
# Build each Python project found
while IFS= read -r python_dir; do
echo "Building Python project in: $python_dir"
cd "$GITHUB_WORKSPACE/$python_dir"
# Determine Python version and build
if [ -f "pyproject.toml" ]; then
echo "Using pyproject.toml build"
python -m pip install --upgrade pip build
python -m build
elif [ -f "setup.py" ]; then
echo "Using setup.py build"
python -m pip install --upgrade pip setuptools wheel
python setup.py sdist bdist_wheel
fi
cd "$GITHUB_WORKSPACE"
done < /tmp/python_dirs.txt
- name: 'Extract project name from .gitreview'
id: extract-project
if: steps.check-pom-xml.outputs.exists == 'true'
run: |
if [ -f .gitreview ]; then
PROJECT_NAME=$(grep '^project=' .gitreview | cut -d'=' -f2 | sed 's/\.git$//' | tr '/' '-')
echo "project-name=${PROJECT_NAME}" >> $GITHUB_OUTPUT
echo "Detected project: ${PROJECT_NAME}"
else
echo "Error: .gitreview file not found"
exit 1
fi
- name: Load secret from 1Password
if: steps.check-pom-xml.outputs.exists == 'true'
uses: 1password/load-secrets-action@92467eb28f72e8255933372f1e0707c567ce2259 # v4.0.0
with:
export-env: true
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
NEXUS_PASSWORD: "op://elnqtgip7eqavqvgodjbiiaqd4/${{ steps.extract-project.outputs.project-name }}/password"
- name: 'Output SHA1 sum of password'
if: steps.check-pom-xml.outputs.exists == 'true'
env:
NEXUS_PASSWORD: ${{ env.NEXUS_PASSWORD }}
run: |
# Output SHA1 sum of password
VALUE_SHA1=$(printf '%s' "$NEXUS_PASSWORD" | shasum -a 1 | awk '{print $1}')
echo "SHA1 sum of NEXUS_PASSWORD is: $VALUE_SHA1"
- name: 'Generate Maven global settings content'
id: create-settings
if: steps.check-pom-xml.outputs.exists == 'true'
env:
NEXUS_PASSWORD: ${{ env.NEXUS_PASSWORD }}
run: |
# Extract project name from .gitreview file
if [ -f .gitreview ]; then
PROJECT_NAME=$(grep '^project=' .gitreview | cut -d'=' -f2 | sed 's/\.git$//' | tr '/' '-')
echo "Detected project: ${PROJECT_NAME}"
else
echo "Error: .gitreview file not found"
exit 1
fi
# Generate settings content for maven-build-action
{
echo 'settings-content<<SETTINGS_EOF'
cat << EOF
<settings>
<servers>
<server>
<id>ecomp-releases</id>
<username>${PROJECT_NAME}</username>
<password>${NEXUS_PASSWORD}</password>
</server>
<server>
<id>ecomp-snapshots</id>
<username>${PROJECT_NAME}</username>
<password>${NEXUS_PASSWORD}</password>
</server>
<server>
<id>onap-releases</id>
<username>${PROJECT_NAME}</username>
<password>${NEXUS_PASSWORD}</password>
</server>
<server>
<id>onap-snapshots</id>
<username>${PROJECT_NAME}</username>
<password>${NEXUS_PASSWORD}</password>
</server>
<server>
<id>nexus3.onap.org:10003</id>
<username>${PROJECT_NAME}</username>
<password>${NEXUS_PASSWORD}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>onap-public</id>
<mirrorOf>*</mirrorOf>
<url>https://nexus.onap.org/content/groups/public/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>onap-nexus</id>
<repositories>
<repository>
<id>onap-public</id>
<url>https://nexus.onap.org/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>onap-public</id>
<url>https://nexus.onap.org/content/groups/public/</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>onap-nexus</activeProfile>
</activeProfiles>
</settings>
EOF
echo 'SETTINGS_EOF'
} >> $GITHUB_OUTPUT
- name: 'Build with Maven'
if: steps.check-pom-xml.outputs.exists == 'true'
continue-on-error: true
# yamllint disable-line rule:line-length
uses: lfreleng-actions/maven-build-action@3e8765bbc2685951fb7c2be03964304179106b70 # v0.2.1
with:
java-version: |
17
21
distribution: 'temurin'
mvn-version: '3.9.5'
mvn-phases: 'clean package'
mvn-params: '-DskipTests -Djib.skip=true --fail-at-end'
# yamllint disable-line rule:line-length
mvn-opts: '-Ddocker.push.registry=nexus3.onap.org:10003 -Ddocker.pull.registry=nexus3.onap.org:10003 -Dmaven.repo.local=/tmp/r -Dorg.ops4j.pax.url.mvn.localRepository=/tmp/r -DaltDeploymentRepository=staging::default::file:"${GITHUB_WORKSPACE}"/m2repo -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn'
global-settings: |
${{ steps.create-settings.outputs.settings-content }}
run-jacoco: 'false'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: 'Create CBOM'
if: steps.check-pom-xml.outputs.exists == 'true' || steps.find-python.outputs.has-python == 'true'
# yamllint disable-line rule:line-length
uses: PQCA/cbomkit-action@7a967459c9d63b56869ca03fae7a2056eceefb8d # v2.2.0
id: cbom
env:
CBOMKIT_LANGUAGES: java, python # or java or python
- name: 'Commit changes to new branch'
# Allows persisting the CBOMs after job completion and
# sharing them with another job in the same workflow.
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: 'CBOM'
path: ${{ steps.cbom.outputs.pattern }}
if-no-files-found: warn
report-status:
if: ${{ always() && github.event_name == 'workflow_dispatch' && inputs.GERRIT_DISABLED != true }}
needs: [notify, cbom-create]
runs-on: ubuntu-latest
steps:
# Harden the runner used by this workflow
# yamllint disable-line rule:line-length
- uses: step-security/harden-runner@ab7a9404c0f3da075243ca237b5fac12c98deaa5 # v2.19.3
with:
egress-policy: audit
- name: Get workflow conclusion
uses: im-open/workflow-conclusion@7b146947e59eaf7fc3328822357861ab1758c088 # v2.2.5
- name: Report workflow conclusion
# yamllint disable-line rule:line-length
uses: lfreleng-actions/gerrit-review-action@91db81bb09f604bb620810640c045eeb1f6a9e54 # v1.1.0
with:
host: ${{ vars.GERRIT_SERVER }}
username: ${{ vars.GERRIT_SSH_USER }}
key: ${{ secrets.GERRIT_SSH_PRIVKEY }}
known_hosts: ${{ vars.GERRIT_KNOWN_HOSTS }}
gerrit-change-number: ${{ inputs.GERRIT_CHANGE_NUMBER }}
gerrit-patchset-number: ${{ inputs.GERRIT_PATCHSET_NUMBER }}
vote-type: ${{ env.WORKFLOW_CONCLUSION }}