Skip to content
Draft
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
30 changes: 28 additions & 2 deletions .github/workflows/publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,40 @@ jobs:
application_id: ${{ vars.DEVOPS_ACTIONS_APPLICATION_ID }}
application_private_key: ${{ secrets.DEVOPS_ACTIONS_APPLICATION_KEY }}

# generate SBOM for the release
- name: Generate SBOM
env:
GH_TOKEN: ${{ steps.get_workflow_token.outputs.token }}
run: |
echo "Generating SBOM for ${{ github.repository }}"
gh api repos/${{ github.repository }}/dependency-graph/sbom \
--jq '.sbom' \
> sbom.spdx.json

# Verify SBOM was generated
if [ ! -f sbom.spdx.json ] || [ ! -s sbom.spdx.json ]; then
echo "Failed to generate SBOM"
exit 1
fi

echo "SBOM generated successfully"
echo "SBOM size: $(wc -c < sbom.spdx.json) bytes"

# publish a release with the build assets
- uses: rajbos-actions/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
id: publish
with:
name: Release ${{ steps.tag.outputs.tag }}
tag_name: ${{ github.ref }}
body: Release ${{ steps.tag.outputs.tag }} is available now
files: ./dist/main.js
body: |
Release ${{ steps.tag.outputs.tag }} is available now

## Release Assets
- `main.js` - The compiled action
- `sbom.spdx.json` - Software Bill of Materials (SBOM) in SPDX format
files: |
./dist/main.js
./sbom.spdx.json
token: ${{ steps.get_workflow_token.outputs.token }}

- run: |
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Can be used to verify the amount of runners for a label is as expected.

[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/devops-actions/load-runner-info/badge)](https://api.securityscorecards.dev/projects/github.com/devops-actions/load-runner-info)

## Security

All releases include a Software Bill of Materials (SBOM) in SPDX format (`sbom.spdx.json`) that provides detailed information about the dependencies used in this action. The SBOM is generated from GitHub's dependency graph and included as a release asset.

# Example
Basic usage:
``` yaml
Expand Down
35 changes: 35 additions & 0 deletions __tests__/workflow.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {expect, test} from '@jest/globals'
import fs from 'fs'
import yaml from 'js-yaml'
import path from 'path'

test('publishing workflow includes SBOM generation', () => {
const workflowPath = path.resolve('.github/workflows/publishing.yml')
expect(fs.existsSync(workflowPath)).toBe(true)

const workflowContent = fs.readFileSync(workflowPath, 'utf8')
const workflow = yaml.load(workflowContent) as any

expect(workflow).toBeDefined()
expect(workflow.jobs).toBeDefined()
expect(workflow.jobs.publish).toBeDefined()

const publishJob = workflow.jobs.publish
expect(publishJob.steps).toBeDefined()

// Check that SBOM generation step exists
const sbomStep = publishJob.steps.find((step: any) =>
step.name && step.name.includes('Generate SBOM')
)
expect(sbomStep).toBeDefined()
expect(sbomStep.run).toContain('gh api')
expect(sbomStep.run).toContain('dependency-graph/sbom')

// Check that release step includes SBOM file
const releaseStep = publishJob.steps.find((step: any) =>
step.uses && step.uses.includes('action-gh-release')
)
expect(releaseStep).toBeDefined()
expect(releaseStep.with.files).toContain('sbom.spdx.json')
expect(releaseStep.with.body).toContain('SBOM')
})
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"yaml": "^2.8.0"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/node": "^24.0.7",
"@typescript-eslint/eslint-plugin": "^8.35.0",
"@typescript-eslint/parser": "^8.35.0",
Expand Down