Add release catalog dispatch action - #134
Conversation
Created with Codex (GPT-5).
KyleFromNVIDIA
left a comment
There was a problem hiding this comment.
Approved with a few small nitpicks
| jq -n \ | ||
| --arg artifact_name "${RELEASE_SOURCE_ARTIFACT_NAME}" \ | ||
| --arg manifest_name "${RELEASE_MANIFEST_NAME}" \ | ||
| --arg repository "${GITHUB_REPOSITORY:-}" \ | ||
| --arg run_attempt "${GITHUB_RUN_ATTEMPT:-}" \ | ||
| --arg run_id "${GITHUB_RUN_ID:-}" \ | ||
| --arg sha "${source_sha}" \ | ||
| --arg unit_id "${RELEASE_UNIT}" \ | ||
| --arg workflow_ref "${GITHUB_WORKFLOW_REF:-}" \ | ||
| --argjson artifact_metadata "${artifact_metadata}" \ | ||
| '{ | ||
| schema_version: 1, | ||
| producer: "shared-workflows", | ||
| release_unit: $unit_id, | ||
| source_artifact: $artifact_name, | ||
| build_output_manifest: $manifest_name, | ||
| build_environment: { | ||
| repository: $repository, | ||
| sha: $sha, | ||
| workflow_ref: $workflow_ref, | ||
| run_id: $run_id, | ||
| run_attempt: $run_attempt | ||
| }, | ||
| metadata: {artifacts: $artifact_metadata} | ||
| }' | jq -S . >"${metadata_path}" |
There was a problem hiding this comment.
| jq -n \ | |
| --arg artifact_name "${RELEASE_SOURCE_ARTIFACT_NAME}" \ | |
| --arg manifest_name "${RELEASE_MANIFEST_NAME}" \ | |
| --arg repository "${GITHUB_REPOSITORY:-}" \ | |
| --arg run_attempt "${GITHUB_RUN_ATTEMPT:-}" \ | |
| --arg run_id "${GITHUB_RUN_ID:-}" \ | |
| --arg sha "${source_sha}" \ | |
| --arg unit_id "${RELEASE_UNIT}" \ | |
| --arg workflow_ref "${GITHUB_WORKFLOW_REF:-}" \ | |
| --argjson artifact_metadata "${artifact_metadata}" \ | |
| '{ | |
| schema_version: 1, | |
| producer: "shared-workflows", | |
| release_unit: $unit_id, | |
| source_artifact: $artifact_name, | |
| build_output_manifest: $manifest_name, | |
| build_environment: { | |
| repository: $repository, | |
| sha: $sha, | |
| workflow_ref: $workflow_ref, | |
| run_id: $run_id, | |
| run_attempt: $run_attempt | |
| }, | |
| metadata: {artifacts: $artifact_metadata} | |
| }' | jq -S . >"${metadata_path}" | |
| jq -n -S \ | |
| --arg artifact_name "${RELEASE_SOURCE_ARTIFACT_NAME}" \ | |
| --arg manifest_name "${RELEASE_MANIFEST_NAME}" \ | |
| --arg repository "${GITHUB_REPOSITORY:-}" \ | |
| --arg run_attempt "${GITHUB_RUN_ATTEMPT:-}" \ | |
| --arg run_id "${GITHUB_RUN_ID:-}" \ | |
| --arg sha "${source_sha}" \ | |
| --arg unit_id "${RELEASE_UNIT}" \ | |
| --arg workflow_ref "${GITHUB_WORKFLOW_REF:-}" \ | |
| --argjson artifact_metadata "${artifact_metadata}" \ | |
| '{ | |
| schema_version: 1, | |
| producer: "shared-workflows", | |
| release_unit: $unit_id, | |
| source_artifact: $artifact_name, | |
| build_output_manifest: $manifest_name, | |
| build_environment: { | |
| repository: $repository, | |
| sha: $sha, | |
| workflow_ref: $workflow_ref, | |
| run_id: $run_id, | |
| run_attempt: $run_attempt | |
| }, | |
| metadata: {artifacts: $artifact_metadata} | |
| }' >"${metadata_path}" |
| jq -n \ | ||
| --arg artifact_digest "${artifact_digest}" \ | ||
| --arg artifact_path "${primary_path}" \ | ||
| --arg repository "${GITHUB_REPOSITORY:-}" \ | ||
| --arg run_attempt "${GITHUB_RUN_ATTEMPT:-}" \ | ||
| --arg run_id "${GITHUB_RUN_ID:-}" \ | ||
| --arg source_sha "${source_sha}" \ | ||
| --arg workflow_ref "${GITHUB_WORKFLOW_REF:-}" \ | ||
| --argjson package "${package}" \ | ||
| '{ | ||
| _type: "https://in-toto.io/Statement/v1", | ||
| subject: [{name: $artifact_path, digest: {sha256: $artifact_digest}}], | ||
| predicateType: "https://slsa.dev/provenance/v1", | ||
| predicate: { | ||
| buildDefinition: { | ||
| buildType: "https://rapids.ai/release-platform/build-output/v1", | ||
| externalParameters: {release_unit: env.RELEASE_UNIT, package: $package}, | ||
| resolvedDependencies: [{ | ||
| uri: ("git+https://github.com/" + $repository + "@" + $source_sha), | ||
| digest: {gitCommit: $source_sha} | ||
| }] | ||
| }, | ||
| runDetails: { | ||
| builder: {id: ("https://github.com/" + $workflow_ref)}, | ||
| metadata: {invocationId: ("https://github.com/" + $repository + "/actions/runs/" + $run_id + "/attempts/" + $run_attempt)} | ||
| } | ||
| } | ||
| }' | jq -S . >"${output_directory}/${destination}" |
There was a problem hiding this comment.
| jq -n \ | |
| --arg artifact_digest "${artifact_digest}" \ | |
| --arg artifact_path "${primary_path}" \ | |
| --arg repository "${GITHUB_REPOSITORY:-}" \ | |
| --arg run_attempt "${GITHUB_RUN_ATTEMPT:-}" \ | |
| --arg run_id "${GITHUB_RUN_ID:-}" \ | |
| --arg source_sha "${source_sha}" \ | |
| --arg workflow_ref "${GITHUB_WORKFLOW_REF:-}" \ | |
| --argjson package "${package}" \ | |
| '{ | |
| _type: "https://in-toto.io/Statement/v1", | |
| subject: [{name: $artifact_path, digest: {sha256: $artifact_digest}}], | |
| predicateType: "https://slsa.dev/provenance/v1", | |
| predicate: { | |
| buildDefinition: { | |
| buildType: "https://rapids.ai/release-platform/build-output/v1", | |
| externalParameters: {release_unit: env.RELEASE_UNIT, package: $package}, | |
| resolvedDependencies: [{ | |
| uri: ("git+https://github.com/" + $repository + "@" + $source_sha), | |
| digest: {gitCommit: $source_sha} | |
| }] | |
| }, | |
| runDetails: { | |
| builder: {id: ("https://github.com/" + $workflow_ref)}, | |
| metadata: {invocationId: ("https://github.com/" + $repository + "/actions/runs/" + $run_id + "/attempts/" + $run_attempt)} | |
| } | |
| } | |
| }' | jq -S . >"${output_directory}/${destination}" | |
| jq -n -S \ | |
| --arg artifact_digest "${artifact_digest}" \ | |
| --arg artifact_path "${primary_path}" \ | |
| --arg repository "${GITHUB_REPOSITORY:-}" \ | |
| --arg run_attempt "${GITHUB_RUN_ATTEMPT:-}" \ | |
| --arg run_id "${GITHUB_RUN_ID:-}" \ | |
| --arg source_sha "${source_sha}" \ | |
| --arg workflow_ref "${GITHUB_WORKFLOW_REF:-}" \ | |
| --argjson package "${package}" \ | |
| '{ | |
| _type: "https://in-toto.io/Statement/v1", | |
| subject: [{name: $artifact_path, digest: {sha256: $artifact_digest}}], | |
| predicateType: "https://slsa.dev/provenance/v1", | |
| predicate: { | |
| buildDefinition: { | |
| buildType: "https://rapids.ai/release-platform/build-output/v1", | |
| externalParameters: {release_unit: env.RELEASE_UNIT, package: $package}, | |
| resolvedDependencies: [{ | |
| uri: ("git+https://github.com/" + $repository + "@" + $source_sha), | |
| digest: {gitCommit: $source_sha} | |
| }] | |
| }, | |
| runDetails: { | |
| builder: {id: ("https://github.com/" + $workflow_ref)}, | |
| metadata: {invocationId: ("https://github.com/" + $repository + "/actions/runs/" + $run_id + "/attempts/" + $run_attempt)} | |
| } | |
| } | |
| }' >"${output_directory}/${destination}" |
| jq -n \ | ||
| --arg artifact_digest "${artifact_digest}" \ | ||
| --arg artifact_path "${primary_path}" \ | ||
| --argjson package "${package}" \ | ||
| '{ | ||
| spdxVersion: "SPDX-2.3", | ||
| dataLicense: "CC0-1.0", | ||
| SPDXID: "SPDXRef-DOCUMENT", | ||
| name: ("RAPIDS release artifact " + $artifact_path), | ||
| documentNamespace: ("https://rapids.ai/release-platform/spdx/" + $artifact_digest), | ||
| creationInfo: { | ||
| creators: ["Tool: rapidsai/shared-workflows release-build-output"], | ||
| created: (now | strftime("%Y-%m-%dT%H:%M:%SZ")) | ||
| }, | ||
| documentDescribes: ["SPDXRef-Artifact"], | ||
| packages: [{ | ||
| SPDXID: "SPDXRef-Artifact", | ||
| name: $package.name, | ||
| versionInfo: $package.version, | ||
| downloadLocation: "NOASSERTION", | ||
| filesAnalyzed: false, | ||
| checksums: [{algorithm: "SHA256", checksumValue: $artifact_digest}] | ||
| }], | ||
| relationships: [{ | ||
| spdxElementId: "SPDXRef-DOCUMENT", | ||
| relationshipType: "DESCRIBES", | ||
| relatedSpdxElement: "SPDXRef-Artifact" | ||
| }], | ||
| comment: "Artifact-identity SBOM envelope. A producer-supplied dependency SBOM may replace this record." | ||
| }' | jq -S . >"${output_directory}/${destination}" |
There was a problem hiding this comment.
| jq -n \ | |
| --arg artifact_digest "${artifact_digest}" \ | |
| --arg artifact_path "${primary_path}" \ | |
| --argjson package "${package}" \ | |
| '{ | |
| spdxVersion: "SPDX-2.3", | |
| dataLicense: "CC0-1.0", | |
| SPDXID: "SPDXRef-DOCUMENT", | |
| name: ("RAPIDS release artifact " + $artifact_path), | |
| documentNamespace: ("https://rapids.ai/release-platform/spdx/" + $artifact_digest), | |
| creationInfo: { | |
| creators: ["Tool: rapidsai/shared-workflows release-build-output"], | |
| created: (now | strftime("%Y-%m-%dT%H:%M:%SZ")) | |
| }, | |
| documentDescribes: ["SPDXRef-Artifact"], | |
| packages: [{ | |
| SPDXID: "SPDXRef-Artifact", | |
| name: $package.name, | |
| versionInfo: $package.version, | |
| downloadLocation: "NOASSERTION", | |
| filesAnalyzed: false, | |
| checksums: [{algorithm: "SHA256", checksumValue: $artifact_digest}] | |
| }], | |
| relationships: [{ | |
| spdxElementId: "SPDXRef-DOCUMENT", | |
| relationshipType: "DESCRIBES", | |
| relatedSpdxElement: "SPDXRef-Artifact" | |
| }], | |
| comment: "Artifact-identity SBOM envelope. A producer-supplied dependency SBOM may replace this record." | |
| }' | jq -S . >"${output_directory}/${destination}" | |
| jq -n -S \ | |
| --arg artifact_digest "${artifact_digest}" \ | |
| --arg artifact_path "${primary_path}" \ | |
| --argjson package "${package}" \ | |
| '{ | |
| spdxVersion: "SPDX-2.3", | |
| dataLicense: "CC0-1.0", | |
| SPDXID: "SPDXRef-DOCUMENT", | |
| name: ("RAPIDS release artifact " + $artifact_path), | |
| documentNamespace: ("https://rapids.ai/release-platform/spdx/" + $artifact_digest), | |
| creationInfo: { | |
| creators: ["Tool: rapidsai/shared-workflows release-build-output"], | |
| created: (now | strftime("%Y-%m-%dT%H:%M:%SZ")) | |
| }, | |
| documentDescribes: ["SPDXRef-Artifact"], | |
| packages: [{ | |
| SPDXID: "SPDXRef-Artifact", | |
| name: $package.name, | |
| versionInfo: $package.version, | |
| downloadLocation: "NOASSERTION", | |
| filesAnalyzed: false, | |
| checksums: [{algorithm: "SHA256", checksumValue: $artifact_digest}] | |
| }], | |
| relationships: [{ | |
| spdxElementId: "SPDXRef-DOCUMENT", | |
| relationshipType: "DESCRIBES", | |
| relatedSpdxElement: "SPDXRef-Artifact" | |
| }], | |
| comment: "Artifact-identity SBOM envelope. A producer-supplied dependency SBOM may replace this record." | |
| }' >"${output_directory}/${destination}" |
| and ((.build // "") | type == "string") | ||
| and ((.platform // "") | type == "string") | ||
| ' <<<"${RELEASE_PACKAGE}" >/dev/null; then | ||
| echo "release-package must be a package object with ecosystem and name; version is optional for Conda and wheel artifacts" >&2 |
There was a problem hiding this comment.
Any chance we could ensure version is present for custom artifacts?
| if [[ "${RELEASE_PACKAGE_FILE}" == /* || "${RELEASE_PACKAGE_FILE}" == */../* || "${RELEASE_PACKAGE_FILE}" == ../* || "${RELEASE_PACKAGE_FILE}" == *"/.." ]]; then | ||
| echo "release-package-file must be a relative path inside output-directory: ${RELEASE_PACKAGE_FILE}" >&2 | ||
| exit 1 | ||
| fi |
There was a problem hiding this comment.
This can use ensure_relative_pattern
|
Thanks, Kyle. Codex and I applied the three jq -n -S suggestions after verifying that they produce byte-identical sorted JSON to the existing jq -n … | jq -S . pipelines while avoiding the second jq process. I also moved ensure_relative_pattern before package-file handling and now reuse it for release-package-file. On requiring version for custom artifacts: the final merged package already requires a version. Conda and wheel versions may be derived from the artifact when absent; other ecosystems, including archive and Maven-style custom artifacts, fail with release-package version is required for artifacts. I did not require version specifically on the base package object because an artifact descriptor may supply it as a package override. I clarified the validation message and added a regression test proving a custom archive without a final version is rejected. |
|
/merge |
Posted by Codex (GPT-5) on behalf of @msarahan. This pull request description is LLM-generated; readers should treat its content accordingly.
What is this?
This introduced the reusable dispatch action that creates job-level release catalog entries and build-time evidence for artifacts produced by RAPIDS open-source builds. It supports:
rapidsai/release-scripts#102; andThe implementation follows the existing dispatch pattern instead of placing all logic in
shared-workflows.rapidsai/shared-workflows#609owns producer integration.This PR used the predecessor naming present at the time it merged.
rapidsai/shared-actions#136defines the currentrelease-catalog-dispatchinterface and its atomicrelease-catalog-entries.jsonenvelope. The entries selected across build jobs are validated and aggregated by the release platform into the release catalog.