diff --git a/.github/workflows/ci-main-pull-request.yml b/.github/workflows/ci-main-pull-request.yml
index d677565..bd09310 100644
--- a/.github/workflows/ci-main-pull-request.yml
+++ b/.github/workflows/ci-main-pull-request.yml
@@ -96,6 +96,21 @@ on:
required: false
type: string
default: 'scc-complexity'
+ scc-version:
+ description: 'Version of SCC workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
+ perform-dco-check:
+ description: 'Perform DCO (Developer Certificate of Origin) check on pull requests'
+ required: false
+ type: boolean
+ default: true
+ dco-version:
+ description: 'Version of DCO check workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
perform-language-linting:
description: 'Perform language-specific linting and pre-compilation checks'
required: false
@@ -111,6 +126,11 @@ on:
required: false
type: boolean
default: true
+ trufflehog-version:
+ description: 'Version of Trufflehog workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
perform-trivy-scan:
description: 'Perform Trivy scan'
required: false
@@ -146,6 +166,11 @@ on:
required: false
type: boolean
default: false
+ grype-version:
+ description: 'Version of Grype workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
grype-image-fail-on-high:
description: 'Fail pipeline if Grype image scan finds HIGH vulnerabilities'
required: false
@@ -166,6 +191,11 @@ on:
required: false
type: boolean
default: false
+ grype-hab-workflow-version:
+ description: 'Version of Grype Habitat package scan workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
grype-hab-build-package:
description: 'Build Habitat package from source before scanning (requires checkout)'
required: false
@@ -248,6 +278,11 @@ on:
required: false
type: boolean
default: false
+ polaris-version:
+ description: 'Version of Polaris SAST workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
polaris-application-name:
description: 'Polaris application name, one of these {Chef-Agents | Chef-Automate | Chef-Chef360 | Chef-Habitat | Chef-Infrastructure-Server | Chef-Shared-Services}'
required: false
@@ -347,7 +382,12 @@ on:
description: 'Report Sonar test coverage and other metrics to Atlassian dashboard (Irfans QA dashboard)'
required: false
type: boolean
- default: true
+ default: true
+ quality-dashboard-version:
+ description: 'Version of quality dashboard workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
quality-product-name:
description: 'Product name for quality reporting (Chef360, Courier, Inspec)'
required: false
@@ -440,6 +480,11 @@ on:
required: false
type: boolean
default: true
+ sbom-version:
+ description: 'Version of SBOM workflow to use (e.g., main, v1.0.7)'
+ required: false
+ type: string
+ default: 'main'
export-github-sbom:
description: 'Export SBOM to GitHub'
required: false
@@ -734,7 +779,7 @@ jobs:
scc:
name: 'Source code complexity checks'
if: ${{ inputs.perform-complexity-checks == true }}
- uses: chef/common-github-actions/.github/workflows/scc.yml@main
+ uses: chef/common-github-actions/.github/workflows/scc.yml@${{ inputs.scc-version }}
needs: checkout
with:
outputfilename: ${{ inputs.scc-output-filename }}
@@ -859,7 +904,7 @@ jobs:
run-trufflehog:
name: 'Trufflehog scan'
if: ${{ inputs.perform-trufflehog-scan }}
- uses: chef/common-github-actions/.github/workflows/trufflehog.yml@main
+ uses: chef/common-github-actions/.github/workflows/trufflehog.yml@${{ inputs.trufflehog-version }}
needs: checkout
with:
github-event-name: ${{ inputs.github-event-name }}
@@ -979,7 +1024,7 @@ jobs:
run-grype-image:
name: 'Grype Docker image scan'
if: ${{ inputs.perform-grype-image-scan }}
- uses: chef/common-github-actions/.github/workflows/grype.yml@main
+ uses: chef/common-github-actions/.github/workflows/grype.yml@${{ inputs.grype-version }}
needs: checkout
secrets: inherit
with:
@@ -990,7 +1035,7 @@ jobs:
run-grype-hab-package-scan:
name: 'Grype scan Habitat packages from bldr.habitat.sh'
if: ${{ inputs.perform-grype-hab-scan == true }}
- uses: chef/common-github-actions/.github/workflows/grype-hab-package-scan.yml@main
+ uses: chef/common-github-actions/.github/workflows/grype-hab-package-scan.yml@${{ inputs.grype-hab-workflow-version }}
needs: checkout
secrets: inherit
with:
@@ -1301,7 +1346,7 @@ jobs:
BlackDuck-Polaris-SAST:
name: 'BlackDuck Polaris SAST scan'
if: ${{ inputs.perform-blackduck-polaris }}
- uses: chef/common-github-actions/.github/workflows/polaris-sast.yml@main
+ uses: chef/common-github-actions/.github/workflows/polaris-sast.yml@${{ inputs.polaris-version }}
needs: checkout
secrets: inherit
with:
@@ -1568,7 +1613,7 @@ jobs:
name: 'Generating SBOM'
# Create software bill-of-materials (SBOM) using SPDX format
if: ${{ inputs.generate-sbom == true }}
- uses: chef/common-github-actions/.github/workflows/sbom.yml@main
+ uses: chef/common-github-actions/.github/workflows/sbom.yml@${{ inputs.sbom-version }}
needs: checkout # TODO: fix set-application-version
secrets: inherit
with:
@@ -1599,7 +1644,7 @@ jobs:
id-token: write
contents: read
if: ${{ inputs.report-to-atlassian-dashboard == true && success() }}
- uses: chef/common-github-actions/.github/workflows/irfan-quality-dashboard.yml@main
+ uses: chef/common-github-actions/.github/workflows/irfan-quality-dashboard.yml@${{ inputs.quality-dashboard-version }}
with:
perform-build: ${{ inputs.build }} # was ${{ inputs.perform-sonar-build }}
build-profile: ${{ inputs.build-profile }}
diff --git a/.github/workflows/dco-check.yml b/.github/workflows/dco-check.yml
new file mode 100644
index 0000000..a33d439
--- /dev/null
+++ b/.github/workflows/dco-check.yml
@@ -0,0 +1,45 @@
+# DCO (Developer Certificate of Origin) Check
+#
+# Verifies that all commits in a pull request are signed off with DCO
+#
+# See https://developercertificate.org/ for more information about DCO
+
+name: DCO Check
+
+on:
+ workflow_call:
+ inputs:
+ github-event-name:
+ description: 'GitHub event name (pass github.event_name from calling workflow)'
+ required: false
+ type: string
+ default: ''
+
+permissions: {}
+
+jobs:
+ dco_check_job:
+ permissions:
+ contents: read
+ pull-requests: read
+ runs-on: ubuntu-latest
+ name: DCO Check
+ steps:
+ - name: Skip if not pull request
+ if: ${{ inputs.github-event-name != 'pull_request' && inputs.github-event-name != 'pull_request_target' }}
+ run: |
+ echo "DCO check only runs on pull_request events. Skipping..."
+ exit 0
+
+ - name: Get PR Commits
+ if: ${{ inputs.github-event-name == 'pull_request' || inputs.github-event-name == 'pull_request_target' }}
+ uses: tim-actions/get-pr-commits@master
+ id: 'get-pr-commits'
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: DCO Check
+ if: ${{ inputs.github-event-name == 'pull_request' || inputs.github-event-name == 'pull_request_target' }}
+ uses: tim-actions/dco@master
+ with:
+ commits: ${{ steps.get-pr-commits.outputs.commits }}
diff --git a/.github/workflows/stubs/ci-main-pull-request-stub.yml b/.github/workflows/stubs/ci-main-pull-request-stub.yml
index edfacb6..d28d544 100644
--- a/.github/workflows/stubs/ci-main-pull-request-stub.yml
+++ b/.github/workflows/stubs/ci-main-pull-request-stub.yml
@@ -36,11 +36,34 @@ jobs:
detect-version-source-parameter: '' # use for file name
language: 'go' # Go, Ruby, Rust, JavaScript, TypeScript, Python, Java, C#, PHP, other - used for build and SonarQube language setting
+ # ============================================================================
+ # SUB-WORKFLOW VERSION CONTROL (NEW IN v1.0.7+)
+ # ============================================================================
+ # Pin individual scan/workflow versions for stability. Uncomment to use.
+ # All default to 'main' if not specified. Use 'v1.0.7' format for stable versions.
+ # See: https://github.com/chef/common-github-actions/blob/main/HOW-TO-USE.md#sub-workflow-versioning-new
+ # ============================================================================
+ # scc-version: 'main' # Source code complexity checks
+ # dco-version: 'main' # Developer Certificate of Origin check
+ # trufflehog-version: 'main' # Secret scanning (TruffleHog)
+ # grype-version: 'main' # Grype source/image scanning
+ # grype-hab-workflow-version: 'main' # Grype Habitat package scanning
+ # polaris-version: 'main' # BlackDuck Polaris SAST
+ # sbom-version: 'main' # SBOM generation and BlackDuck SCA
+ # quality-dashboard-version: 'main' # Quality dashboard reporting
+
+ # ============================================================================
+ # SECURITY SCANS & CODE QUALITY
+ # ============================================================================
+
# complexity-checks
perform-complexity-checks: true
# scc-output-filename: 'scc-output.txt'
perform-language-linting: false # Perform language-specific linting and pre-compilation checks
+ # DCO (Developer Certificate of Origin) check
+ perform-dco-check: true # Validate commit sign-offs on pull requests
+
# trufflehog secret scanning
perform-trufflehog-scan: true
diff --git a/HOW-TO-USE.md b/HOW-TO-USE.md
index 47beadd..ee4d6bf 100644
--- a/HOW-TO-USE.md
+++ b/HOW-TO-USE.md
@@ -48,6 +48,12 @@ jobs:
with:
visibility: ${{ github.event.repository.visibility }}
language: 'go' # go, ruby, rust
+
+ # Optionally pin individual scan versions (all default to 'main')
+ # trufflehog-version: 'v1.0.7'
+ # grype-version: 'v1.0.7'
+ # sbom-version: 'v1.0.7'
+
perform-complexity-checks: true
perform-trufflehog-scan: true
perform-trivy-scan: true
@@ -102,6 +108,45 @@ Tags follow semantic versioning: `v{MAJOR}.{MINOR}.{PATCH}`
When code is merged to `main` in `common-github-actions`, a new patch tag is automatically created via the `create-release-tag.yml` workflow. Manual version bumps can be triggered via workflow dispatch.
+### Sub-Workflow Versioning (NEW)
+
+**Each security scan can be pinned to its own version independently**, giving you fine-grained control over which scan versions to use:
+
+```yaml
+jobs:
+ ci:
+ uses: chef/common-github-actions/.github/workflows/ci-main-pull-request.yml@v1.0.7
+ with:
+ # Pin individual scan versions
+ scc-version: 'v1.0.7' # Use stable SCC
+ dco-version: 'v1.0.7' # Use stable DCO check
+ trufflehog-version: 'v1.0.7' # Use stable TruffleHog
+ grype-version: 'main' # Use latest Grype
+ grype-hab-workflow-version: 'v1.0.6' # Use older Habitat scan
+ polaris-version: 'v1.0.7' # Use stable Polaris
+ sbom-version: 'v1.0.7' # Use stable SBOM
+ quality-dashboard-version: 'main' # Use latest dashboard
+```
+
+**Benefits:**
+- Pin versions that work well with your project
+- Update individual scans without affecting others
+- Test new scan versions without full pipeline upgrade
+- Avoid breaking changes in production workflows
+- Roll back specific scans if issues arise
+
+**Available Version Inputs:**
+- `scc-version` - Source code complexity checks
+- `dco-version` - Developer Certificate of Origin check
+- `trufflehog-version` - Secret scanning
+- `grype-version` - Grype image/source scanning
+- `grype-hab-workflow-version` - Grype Habitat package scanning
+- `polaris-version` - BlackDuck Polaris SAST
+- `sbom-version` - SBOM generation and BlackDuck SCA
+- `quality-dashboard-version` - Quality dashboard reporting
+
+**Default:** All sub-workflows default to `'main'` if not specified.
+
---
## Available Workflows
@@ -166,6 +211,12 @@ jobs:
version: '1.0.0'
build-profile: 'cli'
+ # Pin scan versions for stability (optional)
+ trufflehog-version: 'v1.0.7'
+ grype-version: 'v1.0.7'
+ polaris-version: 'v1.0.7'
+ sbom-version: 'v1.0.7'
+
# Code Quality
perform-complexity-checks: true
perform-language-linting: true
@@ -259,6 +310,9 @@ jobs:
visibility: ${{ github.event.repository.visibility }}
language: 'go'
+ # Use specific versions for critical scans
+ trufflehog-version: 'v1.0.7' # Pin to stable version
+
# Disable everything except security scans
perform-complexity-checks: false
perform-language-linting: false
@@ -292,6 +346,7 @@ jobs:
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| `perform-complexity-checks` | boolean | `true` | Run SCC complexity checks |
+| `perform-dco-check` | boolean | `true` | Run DCO (Developer Certificate of Origin) check on pull requests |
| `perform-language-linting` | boolean | `true` | Run language-specific linting |
| `perform-trufflehog-scan` | boolean | `true` | Run TruffleHog secret scan |
| `perform-trivy-scan` | boolean | `true` | Run Trivy vulnerability scan |
diff --git a/PIPELINE-REFERENCE.md b/PIPELINE-REFERENCE.md
index ffb863e..dbe7be4 100644
--- a/PIPELINE-REFERENCE.md
+++ b/PIPELINE-REFERENCE.md
@@ -6,6 +6,57 @@ This document provides comprehensive information about the security and quality
## Pipeline Overview
+### Sub-Workflow Versioning
+
+**NEW in v1.0.7+**: Each security scan workflow can be pinned to a specific version independently. This allows you to:
+
+- **Pin stable versions** that work with your project
+- **Update incrementally** - test one scan at a time
+- **Avoid breaking changes** - stay on known-good versions
+- **Roll back easily** - revert specific scans if needed
+
+**Version Control Strategy:**
+
+```yaml
+# Example: Mix stable and latest versions
+jobs:
+ ci:
+ uses: chef/common-github-actions/.github/workflows/ci-main-pull-request.yml@v1.0.7
+ with:
+ # Production-critical scans: pin to tested versions
+ trufflehog-version: 'v1.0.7'
+ polaris-version: 'v1.0.7'
+ sbom-version: 'v1.0.7'
+
+ # Non-blocking scans: use latest
+ scc-version: 'main'
+ grype-version: 'main'
+
+ # Your scan configurations...
+ perform-trufflehog-scan: true
+ perform-blackduck-polaris: true
+ generate-sbom: true
+```
+
+**Available Version Inputs:**
+
+| Input | Workflow | Default | Description |
+|-------|----------|---------|-------------|
+| `scc-version` | scc.yml | `main` | Source code complexity |
+| `dco-version` | dco-check.yml | `main` | Developer Certificate of Origin check |
+| `trufflehog-version` | trufflehog.yml | `main` | Secret scanning |
+| `grype-version` | grype.yml | `main` | Image/source scanning |
+| `grype-hab-workflow-version` | grype-hab-package-scan.yml | `main` | Habitat package scanning |
+| `polaris-version` | polaris-sast.yml | `main` | BlackDuck Polaris SAST |
+| `sbom-version` | sbom.yml | `main` | SBOM + BlackDuck SCA |
+| `quality-dashboard-version` | irfan-quality-dashboard.yml | `main` | Quality reporting |
+
+**Recommendation:** Pin to specific versions (e.g., `v1.0.7`) for production repositories. Use `main` for development/testing repositories to get latest features.
+
+---
+
+## Pipeline Overview
+
```mermaid
graph TD
Start([Pull Request/Push Event]) --> PreCheck[precompilation-checks]
@@ -70,16 +121,20 @@ graph TD
```mermaid
graph LR
- A[scc Job] -->|calls| B[scc.yml]
+ A[scc Job] -->|calls| B[scc.yml@version]
B -->|requires| C[Variables]
C -->|input| D[outputfilename: string]
+ C -->|version| E[scc-version: string]
style A fill:#e1f5ff
style B fill:#d4edff
```
-**Workflow File:** `chef/common-github-actions/.github/workflows/scc.yml`
+**Workflow File:** `chef/common-github-actions/.github/workflows/scc.yml@{version}`
+
+**Version Input:**
+- `scc-version` (string) - Version of SCC workflow to use (e.g., 'main', 'v1.0.7'), default: 'main'
**Required Variables:**
- `outputfilename` (string) - Name of the SCC complexity output file artifact, default: 'scc-complexity'
@@ -88,6 +143,52 @@ graph LR
---
+### **DCO (Developer Certificate of Origin) Check**
+
+**Purpose:** Validates that all commits in a pull request are signed with a Developer Certificate of Origin (DCO), ensuring contributors certify their right to submit the code.
+
+**What it checks:**
+- Presence of "Signed-off-by" line in commit messages
+- Proper DCO signature format
+- All commits in the pull request have valid DCO sign-offs
+
+**Reporting:**
+- Job status (pass/fail) in GitHub Actions
+- Comments on pull requests indicating which commits are missing DCO signatures
+- Detailed logs available in workflow output
+
+#### Job Mapping
+
+```mermaid
+graph LR
+ A[run-dco-check Job] -->|calls| B[dco-check.yml]
+ B -->|requires| C[Variables]
+
+ C -->|input| D[github-event-name: string]
+ C -->|version| E[dco-version: string]
+
+ style A fill:#ffe1e1
+ style B fill:#ffd4d4
+```
+
+**Workflow File:** `chef/common-github-actions/.github/workflows/dco-check.yml@{version}`
+
+**Version Input:**
+- `dco-version` (string) - Version of DCO check workflow to use (e.g., 'main', 'v1.0.7'), default: 'main'
+
+**Required Variables:**
+- `github-event-name` (string) - GitHub event name to determine if this is a pull request event
+
+**Condition:** `inputs.perform-dco-check == true`
+
+**Notes:**
+- Only executes on pull_request events
+- Automatically skipped for push events and other triggers
+- Uses tim-actions/get-pr-commits and tim-actions/dco for validation
+- Contributors can add DCO sign-off using: `git commit -s` or `git commit --signoff`
+
+---
+
## Language-Specific Analysis
### **Linting Tools**
@@ -143,16 +244,20 @@ graph LR
```mermaid
graph LR
- A[run-trufflehog Job] -->|calls| B[trufflehog.yml]
+ A[run-trufflehog Job] -->|calls| B[trufflehog.yml@version]
B -->|requires| C[Variables]
C -->|no inputs| D[None Required]
+ C -->|version| E[trufflehog-version: string]
style A fill:#ffe1e1
style B fill:#ffd4d4
```
-**Workflow File:** `chef/common-github-actions/.github/workflows/trufflehog.yml`
+**Workflow File:** `chef/common-github-actions/.github/workflows/trufflehog.yml@{version}`
+
+**Version Input:**
+- `trufflehog-version` (string) - Version of Trufflehog workflow to use (e.g., 'main', 'v1.0.7'), default: 'main'
**Required Variables:**
- None (inherits secrets automatically)
@@ -228,17 +333,21 @@ graph LR
```mermaid
graph LR
- A[BlackDuck-Polaris-SAST Job] -->|inline steps| B[Inline Implementation]
+ A[BlackDuck-Polaris-SAST Job] -->|calls| B[polaris-sast.yml@version]
B -->|requires| C[Variables]
C -->|secrets| D[POLARIS_SERVER_URL
POLARIS_ACCESS_TOKEN]
C -->|inputs| E[polaris-application-name
polaris-project-name
polaris-working-directory
polaris-config-path
polaris-coverity-config-path
polaris-coverity-build-command
polaris-coverity-clean-command
polaris-coverity-args
polaris-detect-search-depth
polaris-detect-args
polaris-assessment-mode
wait-for-scan]
+ C -->|version| F[polaris-version: string]
style A fill:#ffe1e1
style B fill:#ffd4d4
```
-**Workflow File:** Inline implementation (no separate workflow)
+**Workflow File:** `chef/common-github-actions/.github/workflows/polaris-sast.yml@{version}`
+
+**Version Input:**
+- `polaris-version` (string) - Version of Polaris SAST workflow to use (e.g., 'main', 'v1.0.7'), default: 'main'
**Required Secrets:**
- `POLARIS_SERVER_URL` - BlackDuck Polaris server URL
@@ -429,12 +538,17 @@ graph LR
C -->|secrets| D[HAB_PUBLIC_BLDR_PAT]
C -->|inputs| E[publish-habitat-hab_package
publish-habitat-hab_version
publish-habitat-hab_release
publish-habitat-hab_channel
publish-habitat-hab_auth_token]
+ C -->|version| F[grype-version or grype-hab-workflow-version]
style A fill:#ffe1e1
style B fill:#ffd4d4
```
-**Workflow File:** Inline implementation
+**Workflow File:** Inline implementation (for inline scans) or `grype.yml@{version}` / `grype-hab-package-scan.yml@{version}`
+
+**Version Inputs:**
+- `grype-version` (string) - Version of Grype workflow for image/source scans, default: 'main'
+- `grype-hab-workflow-version` (string) - Version of Grype Habitat package scan workflow, default: 'main'
**Required Secrets:**
- `HAB_PUBLIC_BLDR_PAT` - Habitat Builder personal access token (fallback)
@@ -544,17 +658,21 @@ graph LR
```mermaid
graph LR
- A[generate-sbom Job] -->|calls| B[sbom.yml]
+ A[generate-sbom Job] -->|calls| B[sbom.yml@version]
B -->|requires| C[Variables]
C -->|secrets| D[BLACKDUCK_SBOM_URL
BLACKDUCK_SCA_TOKEN]
C -->|inputs| E[version
export-github-sbom
perform-blackduck-sca-scan
blackduck-project-group-name
blackduck-project-name
generate-msft-sbom
license_scout
go-private-modules]
+ C -->|version| F[sbom-version: string]
style A fill:#e1ffe1
style B fill:#c5f5c5
```
-**Workflow File:** `chef/common-github-actions/.github/workflows/sbom.yml`
+**Workflow File:** `chef/common-github-actions/.github/workflows/sbom.yml@{version}`
+
+**Version Input:**
+- `sbom-version` (string) - Version of SBOM workflow to use (e.g., 'main', 'v1.0.7'), default: 'main'
**Required Secrets:**
- `BLACKDUCK_SBOM_URL` - BlackDuck SCA server URL
@@ -600,16 +718,20 @@ graph LR
```mermaid
graph LR
- A[quality-dashboard Job] -->|calls| B[irfan-quality-dashboard.yml]
+ A[quality-dashboard Job] -->|calls| B[irfan-quality-dashboard.yml@version]
B -->|requires| C[Variables]
C -->|inputs| D[perform-build
build-profile
language
report-unit-test-coverage
report-to-atlassian-dashboard
quality-product-name
quality-sonar-app-name
quality-testing-type
quality-service-name
quality-junit-report
visibility
go-private-modules
udf1, udf2, udf3]
+ C -->|version| E[quality-dashboard-version: string]
style A fill:#f0e1ff
style B fill:#e0c5ff
```
-**Workflow File:** `chef/common-github-actions/.github/workflows/irfan-quality-dashboard.yml`
+**Workflow File:** `chef/common-github-actions/.github/workflows/irfan-quality-dashboard.yml@{version}`
+
+**Version Input:**
+- `quality-dashboard-version` (string) - Version of quality dashboard workflow to use (e.g., 'main', 'v1.0.7'), default: 'main'
**Required Variables:**
- `perform-build` (boolean) - Whether build was performed
@@ -689,6 +811,7 @@ sequenceDiagram
| Tool | Type | Primary Use | Workflow File | Output Location |
|------|------|-------------|---------------|-----------------|
| SCC | Complexity | Code metrics | scc.yml | GitHub Artifacts |
+| DCO Check | Compliance | Commit sign-off validation | dco-check.yml | Actions Logs/PR Comments |
| TruffleHog | Secret Scan | Credential detection | trufflehog.yml | Actions Logs |
| Trivy | Vulnerability | Dependencies & containers | trivy.yml | GitHub Artifacts/Security |
| BlackDuck Polaris | SAST | Security vulnerabilities | Inline | polaris.blackduck.com |