Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
120 changes: 120 additions & 0 deletions rust/generate-sbom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -173,13 +195,32 @@ 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 <target>] \
--describe <crate|binaries|all-cargo-targets> \
--format <json|xml>
```

**Entire workspace**:
```bash
cargo cyclonedx --workspace \
[--target <target>] \
--describe <crate|binaries|all-cargo-targets> \
--format <json|xml>
```

**Specific package in workspace**:
```bash
cargo cyclonedx --package <package-name> \
[--target <target>] \
--describe <crate|binaries|all-cargo-targets> \
--format <json|xml>
```

### CycloneDX Format

The generated SBOM includes:
Expand Down Expand Up @@ -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
Expand Down
32 changes: 31 additions & 1 deletion rust/generate-sbom/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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
Expand All @@ -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