diff --git a/CHANGELOG.md b/CHANGELOG.md index 45ac8bb..7c1749e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Example library CI workflow demonstrating feature matrix testing - Release workflow automation (triggers on release published event) - RELEASE_PROCESS.md documentation for release workflow +- Workspace support for **rust/generate-sbom** action + - `workspace` input to generate SBOM for entire workspace + - `package` input to generate SBOM for specific workspace package + - Enhanced file discovery for workspace-generated SBOMs + - Complete workspace workflow examples in documentation + +### Changed +- **rust/generate-sbom** now supports Cargo workspaces with `--workspace` and `--package` flags +- Updated generate-sbom README with workspace examples and best practices ## [1.0.0] - 2025-12-18 diff --git a/rust/generate-sbom/README.md b/rust/generate-sbom/README.md index c0f34bb..e7e3d34 100644 --- a/rust/generate-sbom/README.md +++ b/rust/generate-sbom/README.md @@ -76,6 +76,26 @@ A composite GitHub Action that generates Software Bill of Materials (SBOM) for R describe: binaries ``` +### Workspace - Entire Workspace + +```yaml +- name: Generate SBOM for entire workspace + uses: your-org/github-actions/rust/generate-sbom@v1 + with: + workspace: true + format: both +``` + +### Workspace - Specific Package + +```yaml +- name: Generate SBOM for specific workspace package + uses: your-org/github-actions/rust/generate-sbom@v1 + with: + package: my-core-library + format: json +``` + ### Complete Workflow with Upload ```yaml @@ -120,6 +140,8 @@ jobs: | `cyclonedx-version` | Version of `cargo-cyclonedx` to use | No | `0.5.7` | | `describe` | What to describe: `crate` (entire crate with targets as subcomponents), `binaries` (separate SBOM per binary), or `all-cargo-targets` (separate SBOM per Cargo target) | No | `crate` | | `target` | Rust target triple (e.g., `x86_64-unknown-linux-gnu`) | No | `''` (default target) | +| `package` | Package to generate SBOM for (for workspaces with multiple packages) | No | `''` | +| `workspace` | Generate SBOM for all workspace members | No | `false` | ### Describe Mode Details @@ -173,6 +195,9 @@ Generated SBOM files follow these naming patterns: ### Command Construction +The action builds commands based on your configuration: + +**Single crate (default)**: ```bash cargo cyclonedx --all \ [--target ] \ @@ -180,6 +205,22 @@ cargo cyclonedx --all \ --format ``` +**Entire workspace**: +```bash +cargo cyclonedx --workspace \ + [--target ] \ + --describe \ + --format +``` + +**Specific package in workspace**: +```bash +cargo cyclonedx --package \ + [--target ] \ + --describe \ + --format +``` + ### CycloneDX Format The generated SBOM includes: @@ -354,6 +395,85 @@ For multi-binary projects: --output merged.cdx.json ``` +### Workspace SBOM Workflow + +Complete workflow for Cargo workspaces with multiple packages: + +```yaml +name: Generate Workspace SBOMs + +on: + push: + branches: [main] + release: + types: [published] + +jobs: + sbom-workspace: + name: Generate SBOM for Entire Workspace + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Cache dependencies + uses: firestoned/github-actions/rust/cache-cargo@v1 + + - name: Build entire workspace + uses: firestoned/github-actions/rust/build-library@v1 + with: + workspace: true + all-features: true + + - name: Generate workspace SBOM + uses: firestoned/github-actions/rust/generate-sbom@v1 + with: + workspace: true + format: both + describe: crate + + - name: Upload workspace SBOM + uses: actions/upload-artifact@v4 + with: + name: workspace-sbom + path: | + **/*.cdx.json + **/*.cdx.xml + + sbom-packages: + name: Generate SBOM per Package + runs-on: ubuntu-latest + strategy: + matrix: + package: + - my-core + - my-cli + - my-utils + steps: + - uses: actions/checkout@v4 + + - name: Cache dependencies + uses: firestoned/github-actions/rust/cache-cargo@v1 + + - name: Build package + uses: firestoned/github-actions/rust/build-library@v1 + with: + package: ${{ matrix.package }} + all-features: true + + - name: Generate package SBOM + uses: firestoned/github-actions/rust/generate-sbom@v1 + with: + package: ${{ matrix.package }} + format: json + describe: crate + + - name: Upload package SBOM + uses: actions/upload-artifact@v4 + with: + name: sbom-${{ matrix.package }} + path: "*.cdx.json" +``` + ## SBOM Use Cases ### 1. Vulnerability Management diff --git a/rust/generate-sbom/action.yaml b/rust/generate-sbom/action.yaml index 3e124f3..9210811 100644 --- a/rust/generate-sbom/action.yaml +++ b/rust/generate-sbom/action.yaml @@ -26,6 +26,14 @@ inputs: description: 'Optional Rust target triple (e.g., x86_64-unknown-linux-gnu)' required: false default: '' + package: + description: 'Package to generate SBOM for (for workspaces with multiple packages)' + required: false + default: '' + workspace: + description: 'Generate SBOM for all workspace members' + required: false + default: 'false' runs: using: 'composite' @@ -48,15 +56,29 @@ runs: shell: bash run: | # Build base command - BASE_CMD="cargo cyclonedx --all" + BASE_CMD="cargo cyclonedx" + + # Add package or workspace flags + if [ "${{ inputs.workspace }}" = "true" ]; then + BASE_CMD="$BASE_CMD --workspace" + echo "Generating SBOM for entire workspace" + elif [ -n "${{ inputs.package }}" ]; then + BASE_CMD="$BASE_CMD --package ${{ inputs.package }}" + echo "Generating SBOM for package: ${{ inputs.package }}" + else + BASE_CMD="$BASE_CMD --all" + echo "Generating SBOM for current crate" + fi # Add target if specified if [ -n "${{ inputs.target }}" ]; then BASE_CMD="$BASE_CMD --target ${{ inputs.target }}" + echo "Target: ${{ inputs.target }}" fi # Add describe option BASE_CMD="$BASE_CMD --describe ${{ inputs.describe }}" + echo "Describe mode: ${{ inputs.describe }}" # Generate JSON if requested if [ "${{ inputs.format }}" = "json" ] || [ "${{ inputs.format }}" = "both" ]; then @@ -71,8 +93,16 @@ runs: fi # List generated files for verification + echo "" echo "Generated SBOM files:" ls -lh *.cdx.* 2>/dev/null || echo "No SBOM files found in current directory" if [ -n "${{ inputs.target }}" ] && [ -d "target/${{ inputs.target }}/release" ]; then + echo "" + echo "Target-specific SBOM files:" ls -lh target/${{ inputs.target }}/release/*.cdx.* 2>/dev/null || true fi + if [ "${{ inputs.workspace }}" = "true" ] || [ -n "${{ inputs.package }}" ]; then + echo "" + echo "Workspace/package SBOM files in target directories:" + find target -name "*.cdx.*" -type f 2>/dev/null || true + fi