| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| dtrack-upload | ||
| notify-talk | ||
| sbom-merge | ||
| trivy-sbom | ||
| README.md | ||
forgejo-actions
Shared composite actions for Forgejo / Codeberg CI.
notify-talk— post a build/run status into a Nextcloud Talk channeltrivy-sbom— CycloneDX SBOM of a container image or filesystemsbom-merge— merge several CycloneDX SBOMs into onedtrack-upload— publish a BOM to Dependency-Track
notify-talk — Nextcloud Talk build/run notification
Posts a Markdown status message into a Nextcloud Talk channel. Use it as a final if: always() step so it reports both success and failure.
- name: Notify Nextcloud Talk
if: always()
uses: https://codeberg.org/datatactics/forgejo-actions/notify-talk@main
with:
status: ${{ job.status }}
env:
TALK_BOT_PASSWORD: ${{ secrets.TALK_BOT_PASSWORD }}
TALK_ROOM: ${{ vars.TALK_ROOM }}
TALK_USER: ${{ vars.TALK_USER }}
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
status |
yes | — | Job result; pass ${{ job.status }} → renders ✅ / ❌ / ⚪ / ❓ |
title |
no | Build |
Header text → ### <icon> <title> |
message |
no | commit message | Body line; falls back to the push commit message when empty |
Required environment (provided by the caller)
The action embeds no credentials and no instance config — the calling job supplies everything via env::
| Env | Suggested source | Value |
|---|---|---|
TALK_BOT_PASSWORD |
repository/org secret | Nextcloud app-password of the bot user |
TALK_ROOM |
variable | Talk conversation token (the last path segment of the chat URL) |
TALK_USER |
variable | Nextcloud bot username |
The action fails fast (set -eu) if any of the three is unset. TALK_ROOM accepts either the bare token or a full chat URL (the last path segment is used).
Custom message example
- name: Notify Nextcloud Talk
if: always()
uses: https://codeberg.org/datatactics/forgejo-actions/notify-talk@main
with:
status: ${{ needs.deploy.result }}
title: "Deploy"
message: "Release ${{ github.ref_name }} deployed (${{ needs.deploy.result }})"
env:
TALK_BOT_PASSWORD: ${{ secrets.TALK_BOT_PASSWORD }}
TALK_ROOM: ${{ vars.TALK_ROOM }}
TALK_USER: ${{ vars.TALK_USER }}
Rendered into Talk:
### ✅ Deploy
**Repo:** <owner>/<repo> **Branch:** <branch> **Author:** <actor>
Release v1.4.0 deployed (success)
[View run](<server>/<owner>/<repo>/actions/runs/<n>)
trivy-sbom — CycloneDX SBOM of a container image or filesystem
Scans a container image or a filesystem path with Trivy (standalone or client/server mode), writes a CycloneDX SBOM, optionally strips licenses, and fails the job if the BOM has no components (guards against silently emitting an empty BOM after a transient scanner/registry hiccup). Pairs with sbom-merge and dtrack-upload.
- name: Trivy SBOM
id: sbom
uses: https://codeberg.org/datatactics/forgejo-actions/trivy-sbom@main
with:
image: docker.io/datatactics/rahla:${{ steps.meta.outputs.version }}
output: sbom_rahla_${{ steps.meta.outputs.version }}.json
env: # optional — only for a private registry
TRIVY_USERNAME: ${{ vars.DOCKERHUB_USER }}
TRIVY_PASSWORD: ${{ secrets.DOCKERHUB_PASS }}
Filesystem scan against a remote Trivy server:
- uses: https://codeberg.org/datatactics/forgejo-actions/trivy-sbom@main
with:
scan-type: fs
path: webapp/
server-url: http://trivy.dependencytrack.svc.cluster.local
output: sbom_webapp.json
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
scan-type |
no | image |
image (a container image) or fs (a filesystem path) |
image |
when scan-type=image |
"" |
Image ref to scan |
path |
no | . |
Filesystem path to scan (used when scan-type=fs) |
server-url |
no | "" |
Trivy client/server URL — when set, scans in client mode (--server) |
output |
no | sbom.json |
SBOM filename |
format |
no | cyclonedx |
Trivy output format |
scanners |
no | vuln |
Trivy scanners |
severity |
no | MEDIUM,HIGH,CRITICAL |
Trivy severities |
trivy-version |
no | v0.69.3 |
Trivy release tag to install (only when trivy is not already on PATH) |
strip-licenses |
no | false |
Delete .licenses from components + metadata.component. Dependency-Track v4 rejected Trivy's license format; v5.0.2 ingests it fine (verified 2026-07) — set true only if you still upload to a DT v4 instance |
min-components |
no | 1 |
Fail if the SBOM has fewer than this many components |
Outputs
| Output | Description |
|---|---|
sbom-file |
Path to the generated SBOM |
component-count |
Number of components in the SBOM |
Registry credentials are not action inputs — Trivy reads TRIVY_USERNAME / TRIVY_PASSWORD (and other TRIVY_*) natively, so pass them via the caller's env:.
sbom-merge — merge CycloneDX SBOMs
Merges two or more CycloneDX SBOMs into one with the CycloneDX CLI — e.g. combine a container-image scan with a filesystem scan before uploading a single project to Dependency-Track.
- name: Scan image
uses: https://codeberg.org/datatactics/forgejo-actions/trivy-sbom@main
with:
{
image: "${{ env.IMAGE_REF }}",
server-url: "${{ env.TRIVY_SERVER }}",
output: sbom_image.json,
}
- name: Scan webapp/
uses: https://codeberg.org/datatactics/forgejo-actions/trivy-sbom@main
with:
{
scan-type: fs,
path: webapp/,
server-url: "${{ env.TRIVY_SERVER }}",
output: sbom_webapp.json,
}
- name: Merge
id: sbom
uses: https://codeberg.org/datatactics/forgejo-actions/sbom-merge@main
with:
input-files: sbom_image.json sbom_webapp.json
output: sbom_merged.json
- name: Upload
uses: https://codeberg.org/datatactics/forgejo-actions/dtrack-upload@main
with:
{
bom: "${{ steps.sbom.outputs.sbom-file }}",
project-name: opsroom,
project-version: "${{ github.ref_name }}",
}
env:
{
DTRACK_URL: "${{ vars.DTRACK_URL }}",
DTRACK_API_KEY: "${{ secrets.DTRACK_API_KEY }}",
}
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
input-files |
yes | — | Space-separated list of BOM files to merge |
output |
no | sbom_merged.json |
Merged SBOM filename |
output-version |
no | v1_6 |
CycloneDX output spec version |
cyclonedx-version |
no | v0.32.0 |
CycloneDX CLI release tag to install (only when cyclonedx is not on PATH) |
Outputs
| Output | Description |
|---|---|
sbom-file |
Path to the merged SBOM |
component-count |
Number of components in the merged SBOM |
dtrack-upload — publish a BOM to Dependency-Track
POSTs a BOM to a Dependency-Track instance (multipart bom upload, autoCreate), then verifies DT returned a processing token — a rejected upload fails the job instead of going green. Optionally polls until DT finishes processing.
- name: Upload SBOM to Dependency-Track
uses: https://codeberg.org/datatactics/forgejo-actions/dtrack-upload@main
with:
bom: ${{ steps.sbom.outputs.sbom-file }}
project-name: datatactics/rahla
project-version: ${{ steps.meta.outputs.version }}
parent-uuid: cff07b40-c95c-47e9-9367-cb9e8df75dcd
env:
DTRACK_URL: ${{ vars.DTRACK_URL }} # the .../api/v1/bom endpoint
DTRACK_API_KEY: ${{ secrets.DTRACK_API_KEY }}
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
bom |
yes | — | Path to the BOM file to upload |
dtrack-url |
no | "" |
Dependency-Track BOM endpoint (falls back to DTRACK_URL) |
dtrack-base-url |
no | "" |
Dependency-Track base URL for status polling (derived from the endpoint if empty) |
dtrack-api-key |
no | "" |
Dependency-Track API key (falls back to DTRACK_API_KEY) |
project-uuid |
no | "" |
Dependency-Track project UUID |
project-name |
no | "" |
Dependency-Track projectName (required unless project-uuid is set) |
project-version |
no | "" |
Dependency-Track projectVersion |
parent-uuid |
no | "" |
Dependency-Track parentUUID |
auto-create |
no | true |
Create the project if it does not exist |
verify-non-empty |
no | true |
Refuse to upload a BOM with 0 components |
wait-for-processing |
no | false |
Poll DT until the BOM finishes processing |
timeout-seconds |
no | 120 |
Max wait when wait-for-processing: true |
Outputs
| Output | Description |
|---|---|
token |
Dependency-Track processing token |
Required environment (provided by the caller)
DTRACK_URL and DTRACK_API_KEY can be supplied either via the dtrack-url/dtrack-api-key inputs above or as the env vars below.
| Env | Suggested source | Value |
|---|---|---|
DTRACK_URL |
variable | The .../api/v1/bom endpoint |
DTRACK_API_KEY |
secret | DT API key with BOM_UPLOAD (+ PROJECT_CREATION_UPLOAD when auto-create: true) permission |
Setup (notify-talk)
The credentials and channel config live outside the action:
- A secret
TALK_BOT_PASSWORD— the Nextcloud app-password of the bot user (repository- or organization-level). - Variables
TALK_ROOM(channel token) andTALK_USER(bot username) — repository-, organization-, or instance-level so they can be shared.
The Nextcloud base URL is configured inside the action.
Conventions
- Use the full action URL. A bare
owner/repo@refresolves against the default actions registry, not the repo you expect — always reference the fullhttps://codeberg.org/...URL. - Pin the ref.
@maintracks latest; pin a tag (e.g.@v1) once releases are tagged for reproducible builds.