Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/actions/commit-releases-json/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,20 @@ runs:
git config user.email "${{ inputs.email }}"
git config user.name "${{ inputs.actor }}"

git add oci/${{ inputs.image-name }}/_releases.json
release_files=()
for release_file in _releases.json _pro_releases.json; do
path="oci/${{ inputs.image-name }}/${release_file}"
if [[ -f "$path" ]]; then
release_files+=("$path")
fi
done

if [[ ${#release_files[@]} -eq 0 ]]; then
echo "No release files found for ${{ inputs.image-name }}" >&2
exit 1
fi

git add -- "${release_files[@]}"
Comment thread
alesancor1 marked this conversation as resolved.
git commit -m "${{ inputs.message }}"

for i in {1..10}; do
Expand Down
12 changes: 9 additions & 3 deletions .github/actions/fetch-releases-json/copy-releases-files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ if [[ "$RUNNER_DEBUG" == "1" ]]; then
fi

if [[ "$image_name" = "*" ]]; then
echo "Copying all _releases.json files"
echo "Copying all _releases.json (including _pro_releases.json) files"
cd "$directory" || exit 1
find . -name "_releases.json" -exec cp --parents {} "$OLDPWD" \;
find . -name "_pro_releases.json" -exec cp --parents {} "$OLDPWD" \;
cd "$OLDPWD" || exit 1
elif [[ -f "$directory/oci/$image_name/_releases.json" ]]; then
cp "$directory/oci/$image_name/_releases.json" "oci/$image_name/_releases.json"
else
if [[ -f "$directory/oci/$image_name/_releases.json" ]]; then
cp "$directory/oci/$image_name/_releases.json" "oci/$image_name/_releases.json"
fi
if [[ -f "$directory/oci/$image_name/_pro_releases.json" ]]; then
cp "$directory/oci/$image_name/_pro_releases.json" "oci/$image_name/_pro_releases.json"
fi
fi
97 changes: 67 additions & 30 deletions .github/actions/fetch-releases-json/test-copy-releases-files.bats
Original file line number Diff line number Diff line change
@@ -1,44 +1,81 @@
#!/usr/bin/env bats

load '/usr/lib/bats/bats-support/load.bash'
load '/usr/lib/bats/bats-assert/load.bash'
setup() {
original_pwd=$PWD
workdir=$(mktemp -d "${BATS_TEST_TMPDIR}/copy-releases.XXXXXX")
releases_dir="${workdir}/releases"
output_dir="${workdir}/output"
mkdir -p \
"${releases_dir}/oci/public-only" \
"${releases_dir}/oci/pro-only" \
"${releases_dir}/oci/both" \
"${output_dir}/oci/public-only" \
"${output_dir}/oci/pro-only" \
"${output_dir}/oci/both"

setup_file() {
echo "setup" >&3
workdir=$(mktemp -d)
pushd "$workdir" || exit 1
git clone https://github.com/canonical/oci-factory.git oci-factory-releases -b _releases --depth 1
popd || exit 1
export workdir
printf '%s\n' '{"source":"public-only"}' > "${releases_dir}/oci/public-only/_releases.json"
printf '%s\n' '{"source":"pro-only"}' > "${releases_dir}/oci/pro-only/_pro_releases.json"
printf '%s\n' '{"source":"both-public"}' > "${releases_dir}/oci/both/_releases.json"
printf '%s\n' '{"source":"both-pro"}' > "${releases_dir}/oci/both/_pro_releases.json"
printf '%s\n' '{"ignored":true}' > "${releases_dir}/oci/both/metadata.json"

cd "$output_dir" || return 1
}

teardown() {
cd "$original_pwd" || return 1
if [[ -n "${workdir:-}" && "$workdir" == "${BATS_TEST_TMPDIR}"/* ]]; then
rm -rf -- "$workdir"
fi
}

@test "copies a public-only release file" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" public-only "$releases_dir"

[[ "$status" -eq 0 ]]
cmp "${releases_dir}/oci/public-only/_releases.json" "oci/public-only/_releases.json"
[[ ! -e "oci/public-only/_pro_releases.json" ]]
}

@test "copy single existing _releases.json file" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" mock-rock "${workdir}/oci-factory-releases"
assert_success
[[ -f "oci/mock-rock/_releases.json" ]]
@test "copies a Pro-only release file" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" pro-only "$releases_dir"

[[ "$status" -eq 0 ]]
cmp "${releases_dir}/oci/pro-only/_pro_releases.json" "oci/pro-only/_pro_releases.json"
[[ ! -e "oci/pro-only/_releases.json" ]]
}

@test "copy single non-existing _releases.json file" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" mock-nonexistent "${workdir}/oci-factory-releases"
assert_success
[[ ! -f "oci/mock-nonexistent/_releases.json" ]]
@test "copies both public and Pro release files" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" both "$releases_dir"

[[ "$status" -eq 0 ]]
cmp "${releases_dir}/oci/both/_releases.json" "oci/both/_releases.json"
cmp "${releases_dir}/oci/both/_pro_releases.json" "oci/both/_pro_releases.json"
}

@test "copy all _releases.json files" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" "*" "${workdir}/oci-factory-releases"
assert_success
run find oci/ -mindepth 1 -maxdepth 1 -type d | xargs -I{} test -f "{}/_releases.json"
assert_success
assert_equal \
"$(find 'oci/' -mindepth 1 -maxdepth 1 -type d | wc -l)" \
"$(find "${workdir}/oci-factory-releases/oci/" -mindepth 1 -maxdepth 1 -type d | wc -l)"
@test "wildcard copies all public and Pro release files only" {
rm -rf -- "${output_dir}/oci"

run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" "*" "$releases_dir"

[[ "$status" -eq 0 ]]
cmp "${releases_dir}/oci/public-only/_releases.json" "oci/public-only/_releases.json"
cmp "${releases_dir}/oci/pro-only/_pro_releases.json" "oci/pro-only/_pro_releases.json"
cmp "${releases_dir}/oci/both/_releases.json" "oci/both/_releases.json"
cmp "${releases_dir}/oci/both/_pro_releases.json" "oci/both/_pro_releases.json"
[[ ! -e "oci/both/metadata.json" ]]
}

@test "fail if directory not found" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" "*" "/nonexistent-directory"
assert_failure
@test "missing image succeeds without creating release files" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" missing "$releases_dir"

[[ "$status" -eq 0 ]]
[[ ! -e "oci/missing/_releases.json" ]]
[[ ! -e "oci/missing/_pro_releases.json" ]]
}

teardown_file() {
find . -name "_releases.json" -exec rm {} \;
@test "wildcard fails for an invalid releases directory" {
run "${BATS_TEST_DIRNAME}/copy-releases-files.sh" "*" "${workdir}/missing-releases"

[[ "$status" -ne 0 ]]
}
5 changes: 5 additions & 0 deletions .github/workflows/Build-Rock.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ jobs:
- name: Check Pro Build
id: check-pro-build
env:
ARTIFACT_PASSPHRASE: ${{ secrets.pro-artifact-passphrase }}
UBUNTU_PRO_TOKEN: ${{ secrets.pro-token }}
INPUTS_PRO_SERVICES: ${{ inputs.pro-services }}
run: |
Expand All @@ -104,6 +105,10 @@ jobs:
echo "Error: 'pro-token' must be provided in order to use 'pro-services'."
exit 1
fi
if [[ -z "${ARTIFACT_PASSPHRASE:-}" ]]; then
echo "Error: 'pro-artifact-passphrase' must be provided in order to use 'pro-services'."
exit 1
fi
echo "pro-build=true" >> "$GITHUB_OUTPUT"
else
echo "pro-build=false" >> "$GITHUB_OUTPUT"
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/Continuous-Testing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ jobs:

- name: Prepare test matrix
id: prepare-test-matrix
run: python3 -m src.tests.get_released_revisions --oci-images-path "$PWD/oci"
run: python3 -m src.tests.get_released_revisions --oci-images-path "$PWD/oci" --acr-registry "${ACR_REGISTRY}"
env:
ACR_REGISTRY: ${{ secrets.ACR_REGISTRY }}

- name: Infer date of last scan
id: last-scan
Expand All @@ -49,9 +51,11 @@ jobs:
matrix: ${{ fromJSON(needs.prepare-test-matrix.outputs.released-revisions-matrix) }}
uses: ./.github/workflows/Vulnerability-Scan.yaml
with:
oci-image-name: "${{ matrix.source-image }}"
oci-image-name: ${{ matrix.pro && format('{0}:{1}', matrix.source-image, matrix.released-tags[0]) || matrix.source-image }}
oci-image-path: "oci/${{ matrix.name }}"
trivyignore-path: "oci/${{ matrix.name }}/.trivyignore"
date-last-scan: ${{ needs.prepare-test-matrix.outputs.last-scan }}
create-issue: true
pro: ${{ matrix.pro }}
released-tags: ${{ join(matrix.released-tags, ',') }}
secrets: inherit
55 changes: 40 additions & 15 deletions .github/workflows/Image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,11 @@ jobs:
rock-repo-commit: ${{ matrix.commit }}
rockfile-directory: ${{ matrix.directory }}
lpci-fallback: true
secrets: inherit
pro-services: ${{ matrix.pro-services }}
secrets:
source-github-token: ${{ secrets.ROCKSBOT_TOKEN }}
pro-token: ${{ secrets.ROCKS_PRO_TOKEN }}
pro-artifact-passphrase: ${{ secrets.ROCKS_PRO_ARTIFACT_PASSPHRASE }}
Comment thread
lczyk marked this conversation as resolved.
Outdated

test-rock:
needs: [prepare-build, build-rock]
Expand All @@ -210,7 +214,8 @@ jobs:
oci-archive-name: "${{ matrix.name }}_${{ matrix.commit }}_${{ matrix.dir_identifier }}"
trivyignore-path: ${{ matrix.ignored-vulnerabilities == '' && format('oci/{0}/.trivyignore', matrix.name) || '' }}
ignored-vulnerabilities: ${{ matrix.ignored-vulnerabilities }}
secrets: inherit
secrets:
pro-artifact-passphrase: ${{ matrix.pro-services != '' && secrets.ROCKS_PRO_ARTIFACT_PASSPHRASE || '' }}

prepare-upload:
runs-on: self-hosted-linux-amd64-noble-private-endpoint-small
Expand Down Expand Up @@ -318,7 +323,7 @@ jobs:
UMOCI_VERSION: "v0.4.7"
UMOCI_BINARY: "umoci.amd64"
outputs:
artefacts-hashes: ${{ steps.artefacts-hashes.outputs.hashes }}
artifacts-hashes: ${{ steps.artifacts-hashes.outputs.hashes }}

permissions:
packages: write
Expand Down Expand Up @@ -350,7 +355,17 @@ jobs:
with:
name: ${{ env.OCI_ARCHIVE_NAME }}

- name: Name output artefact
- name: Decrypt pro artifact
if: ${{ matrix.pro-services != '' }}
uses: ./.github/actions/crypt-artifact
with:
mode: decrypt
input-path: ${{ env.OCI_ARCHIVE_NAME }}.gpg
passphrase: ${{ secrets.ROCKS_PRO_ARTIFACT_PASSPHRASE }}
output-path: ${{ env.OCI_ARCHIVE_NAME }}
preserve-original: false

- name: Name output artifact
id: rename-oci-archive
run: |
# Rename the OCI archive tarball
Expand All @@ -365,11 +380,6 @@ jobs:
MATRIX_REVISION: ${{ matrix.revision }}
MATRIX_NAME: ${{ matrix.name }}

- uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7
with:
path: ${{ steps.rename-oci-archive.outputs.name }}
key: ${{ github.run_id }}-${{ steps.rename-oci-archive.outputs.name }}

- name: Install Syft
uses: anchore/sbom-action/download-syft@e22c389904149dbc22b58101806040fa8d37a610
with:
Expand Down Expand Up @@ -460,8 +470,8 @@ jobs:
name: ${{ env.OCI_ARCHIVE_NAME }}${{ env.VULNERABILITY_REPORT_SUFFIX }}

# https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/generic/README.md
- name: Calculate artefacts hashes
id: artefacts-hashes
- name: Calculate artifacts hashes
id: artifacts-hashes
env:
VULN_REPORT: ${{ env.OCI_ARCHIVE_NAME }}${{ env.VULNERABILITY_REPORT_SUFFIX }}
SBOMS: ${{ steps.generate-sboms.outputs.sboms }}
Expand All @@ -471,10 +481,12 @@ jobs:
if [[ "$RUNNER_DEBUG" == "1" ]]; then
set -x
fi
echo "hashes=$(sha256sum ${VULN_REPORT} ${OCI_IMAGE_ARCHIVE} ${SBOMS} | base64 -w0)"
hashes=$(sha256sum "$VULN_REPORT" "$OCI_IMAGE_ARCHIVE" "$SBOMS" | base64 -w0)
echo "hashes=$hashes" >> "$GITHUB_OUTPUT"

- name: Login to GHCR
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121
if: ${{ matrix.pro-services == '' }}
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -487,16 +499,26 @@ jobs:
path: ${{ steps.generate-sboms.outputs.sboms }}
if-no-files-found: error

- name: Encrypt pro artifact
if: ${{ matrix.pro-services != '' }}
uses: ./.github/actions/crypt-artifact
with:
mode: encrypt
input-path: ${{ steps.rename-oci-archive.outputs.name }}
passphrase: ${{ secrets.ROCKS_PRO_ARTIFACT_PASSPHRASE }}
output-path: ${{ steps.rename-oci-archive.outputs.name }}.gpg

Comment on lines +508 to +516

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

See if this can be optimized, we can just rename the downloaded artifact, and choose to keep the encrypted artifact during the decryption.

- name: Upload image
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
with:
name: ${{ steps.rename-oci-archive.outputs.name }}
path: ${{ steps.rename-oci-archive.outputs.name }}
path: ${{ matrix.pro-services == '' && steps.rename-oci-archive.outputs.name || format('{0}.gpg', steps.rename-oci-archive.outputs.name) }}
if-no-files-found: error

- name: Upload to GHCR
id: upload-image
uses: ./.github/actions/upload-rock
if: ${{ matrix.pro-services == '' }}
with:
artifact_name: ${{ env.OCI_ARCHIVE_NAME }}
name: ${{ github.repository_owner }}/oci-factory/${{ matrix.name }}
Expand All @@ -521,12 +543,15 @@ jobs:
MATRIX_NAME: ${{ matrix.name }}
MATRIX_TRACK: ${{ matrix.track }}
MATRIX_REVISION: ${{ matrix.revision }}
PRO_SERVICES: ${{ matrix.pro-services }}
STEPS_GENERATE_SBOMS_OUTPUTS_SBOMS: ${{ steps.generate-sboms.outputs.sboms }}
run: |
jq --arg base "${MATRIX_BASE}" \
--arg digest "${STEPS_UPLOAD_IMAGE_OUTPUTS_DIGEST}" \
--arg ignored_vulnerabilities "${MATRIX_IGNORED_VULNERABILITIES}" \
'. + {base: $base, digest: $digest, "ignored-vulnerabilities": $ignored_vulnerabilities}' \
--arg pro_services "${PRO_SERVICES}" \
'. + {base: $base, digest: $digest, "ignored-vulnerabilities": $ignored_vulnerabilities}
| if $pro_services != "" then . + {"pro-services": $pro_services} else . end' \
<<< '${{ toJSON(matrix) }}' > build_metadata.json
./src/uploads/upload_to_swift.sh \
"${MATRIX_NAME}" \
Expand Down Expand Up @@ -694,7 +719,7 @@ jobs:
# contents: write # Needed for release uploads
# uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@7f4fdb871876c23e455853d694197440c5a91506
# with:
# base64-subjects: "${{ needs.upload.outputs.artefacts-hashes }}"
# base64-subjects: "${{ needs.upload.outputs.artifacts-hashes }}"

notify:
runs-on: ubuntu-22.04
Expand Down
Loading
Loading