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
4 changes: 3 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ root = true

[*]
end_of_line = lf
insert_final_newline = true
indent_size = 2
indent_style = space
insert_final_newline = true

[*.{js,json,tf*,yml,yaml}]
max_line_length = 180
trim_trailing_whitespace = true

[*.md]
max_line_length = 240
trim_trailing_whitespace = false
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
branches: [main]
workflow_dispatch: {}

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

Expand Down
39 changes: 21 additions & 18 deletions .github/workflows/reusable-container-publication.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,28 +107,31 @@ jobs:
repository: devpro/github-workflow-parts
ref: ${{ inputs.workflow-parts-version }}
path: workflow-parts
# The Docker CLI of the runner does what the docker/* actions wrapped, with no third party action in between.
- name: Login to container registry
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee
with:
registry: ${{ inputs.container-registry }}
username: ${{ secrets.container-registry-username }}
password: ${{ secrets.container-registry-password }}
env:
REGISTRY: ${{ inputs.container-registry }}
REGISTRY_USERNAME: ${{ secrets.container-registry-username }}
REGISTRY_PASSWORD: ${{ secrets.container-registry-password }}
run: echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY" --username "$REGISTRY_USERNAME" --password-stdin
- name: Set up QEMU
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3
# Emulation is only needed for a platform other than the runner's own.
if: ${{ inputs.image-platform != 'linux/amd64' }}
run: docker run --privileged --rm tonistiigi/binfmt --install all
- name: Set up Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5
run: docker buildx create --use --driver docker-container
- name: Build and push container image
id: build-push
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf
with:
context: ${{ inputs.working-directory }}
file: ${{ inputs.image-definition }}
platforms: ${{ inputs.image-platform }}
push: true
tags: ${{ env.IMAGE_REF }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: ${{ inputs.extra-build-arguments }}
# The gha cache backend is reachable from JavaScript actions only, so the build runs without a cache.
env:
IMAGE_DEFINITION: ${{ inputs.image-definition }}
IMAGE_PLATFORM: ${{ inputs.image-platform }}
BUILD_ARGUMENTS: ${{ inputs.extra-build-arguments }}
run: |
args=(--file "$IMAGE_DEFINITION" --platform "$IMAGE_PLATFORM" --tag "$IMAGE_REF" --push)
while IFS= read -r argument; do
[ -n "$argument" ] && args+=(--build-arg "$argument")
done <<< "$BUILD_ARGUMENTS"
docker buildx build "${args[@]}" .
- name: Generate SBOM with Syft
uses: ./workflow-parts/actions/syft/generate-sbom
continue-on-error: true
Expand Down
9 changes: 2 additions & 7 deletions .github/workflows/reusable-dotnet-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,20 +169,15 @@ jobs:
sonar-token: ${{ secrets.sonar-token }}
- name: Check license compliance with FOSSA
if: ${{ inputs.fossa-enabled }}
uses: fossas/fossa-action@ff70fe9fe17cbd2040648f1c45e8ec4e4884dcf3
id: fossa
uses: ./workflow-parts/actions/fossa/analyze
# https://status.fossa.com/
continue-on-error: true
timeout-minutes: 3
with:
api-key: "${{ secrets.fossa-api-key }}"
run-tests: ${{ inputs.fossa-test && github.event_name == 'pull_request' }}
test-diff-revision: ${{ github.event.pull_request.base.sha }}
generate-report: html
- name: Create FOSSA report file
if: ${{ inputs.fossa-enabled && steps.fossa.outcome == 'success' }}
run: echo '${{ steps.fossa.outputs.report }}' > report/fossa.html
continue-on-error: true
report-file: report/fossa.html
- name: Generate SBOM with Syft
uses: ./workflow-parts/actions/syft/generate-sbom
continue-on-error: true
Expand Down
3 changes: 2 additions & 1 deletion .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
gitignore: true
ignores:
- "**/node_modules/**"
- node_modules
- CLAUDE.md
config:
# ref. https://github.com/DavidAnson/markdownlint
default: true
Expand Down
27 changes: 27 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# github-workflow-parts: agent context

GitHub workflow actions and reusable workflows.

Linux or WSL2, Docker and `bash`.

## Working rules

- **Every command runs in the foreground, and the agent waits for it.**
No background commands, no subagents, no forks, no parallel tasks, even for a long commands.
- Headers stay: short documentation still has sections.
- Linters for YAML and Markdown are never run by an agent.
- Commit only when asked, and never push.
Shell scripts are `snake_case` and committed with the executable bit (`git update-index --chmod=+x`).
- Documentation is as short as possible.

## Writing style

Applies to Markdown, code comments, commit messages and prose in scripts.

- **A comment says why, not what, and the why is timeless.**
- **One thought per line.**
Every sentence starts on its own line, and there is no maximum line length.
- **No em dash, no en dash.**
A colon, a comma, or a full stop.
- **No second person.**
"The working tree", not "your working tree"; `<token>`, not `<your-token>`.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
8 changes: 7 additions & 1 deletion actions/cosign/sign/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ runs:
steps:
- name: Install Cosign
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
echo "Downloading Cosign binary and checksums..."
curl -sL -O https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/${COSIGN_BINARY}
curl -sL -O "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/${COSIGN_CHECKSUM_FILE}"
Expand All @@ -42,7 +44,11 @@ runs:
echo "Verification successful!"
rm $COSIGN_CHECKSUM_FILE
chmod +x $COSIGN_BINARY
sudo mv $COSIGN_BINARY /usr/local/bin/cosign
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv $COSIGN_BINARY "${RUNNER_TEMP}/bin/cosign"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
cosign version
else
echo "ERROR: Checksum verification failed!" >&2
Expand Down
2 changes: 1 addition & 1 deletion actions/dotnet/install-lint-restore/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ runs:
- name: Install .NET tools
run: |
dotnet tool install --global dotnet-reportgenerator-globaltool
export PATH="$PATH:/root/.dotnet/tools"
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
shell: bash
- name: Restore .NET packages
run: dotnet restore
Expand Down
93 changes: 93 additions & 0 deletions actions/fossa/analyze/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Analyze with FOSSA
description: |
Installs the FOSSA CLI by downloading the official binary from its GitHub release and verifying its SHA256 checksum,
then analyzes the dependencies for license compliance, optionally tests them against the policy, and writes an HTML report
(replacement for fossas/fossa-action, to reduce third-party GitHub Action supply-chain risk).
Linux runners only (for example ubuntu-latest).

inputs:
fossa-version:
description: Version of the FOSSA CLI to install (check latest from https://github.com/fossas/fossa-cli/releases)
required: false
default: "3.19.3"
api-key:
description: FOSSA API key
required: true
run-tests:
description: Test the analyzed dependencies against the FOSSA policy
required: false
default: "false"
test-diff-revision:
description: Revision to report only the issues introduced since (empty tests everything)
required: false
default: ""
report-file:
description: Path of the generated HTML report (empty writes none)
required: false
default: "report/fossa.html"

runs:
using: "composite"
steps:
- name: Install FOSSA CLI
shell: bash
env:
FOSSA_VERSION: ${{ inputs.fossa-version }}
FOSSA_TARBALL: fossa_${{ inputs.fossa-version }}_linux_amd64.tar.gz
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
BASE_URL="https://github.com/fossas/fossa-cli/releases/download/v${FOSSA_VERSION}"

echo "Downloading FOSSA CLI binary and checksum..."
curl -sSL -O "${BASE_URL}/${FOSSA_TARBALL}"
curl -sSL -O "${BASE_URL}/${FOSSA_TARBALL}.sha256"

echo "Verifying checksum..."
# The checksum file holds the hash, with or without the file name after it.
echo "$(cut -d ' ' -f 1 "${FOSSA_TARBALL}.sha256") ${FOSSA_TARBALL}" | sha256sum --check --status

if [ $? -eq 0 ]; then
echo "Verification successful!"
tar -xzf "${FOSSA_TARBALL}" fossa
chmod +x fossa
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv fossa "${RUNNER_TEMP}/bin/fossa"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
rm -f "${FOSSA_TARBALL}" "${FOSSA_TARBALL}.sha256"
fossa --version
else
echo "ERROR: Checksum verification failed!" >&2
exit 1
fi

- name: Analyze dependencies
shell: bash
env:
FOSSA_API_KEY: ${{ inputs.api-key }}
run: fossa analyze

- name: Test dependencies against the policy
if: ${{ inputs.run-tests == 'true' }}
shell: bash
env:
FOSSA_API_KEY: ${{ inputs.api-key }}
DIFF_REVISION: ${{ inputs.test-diff-revision }}
run: |
if [ -n "$DIFF_REVISION" ]; then
fossa test --diff "$DIFF_REVISION"
else
fossa test
fi

- name: Write HTML report
if: ${{ inputs.report-file != '' }}
shell: bash
env:
FOSSA_API_KEY: ${{ inputs.api-key }}
REPORT_FILE: ${{ inputs.report-file }}
run: |
mkdir -p "$(dirname "$REPORT_FILE")"
fossa report attribution --format html > "$REPORT_FILE"
47 changes: 47 additions & 0 deletions actions/goreleaser/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Setup GoReleaser
description: |
Installs GoReleaser by downloading the official binary from its GitHub release and verifying its SHA256 checksum
(replacement for goreleaser/goreleaser-action, to reduce third-party GitHub Action supply-chain risk).
Linux runners only (for example ubuntu-latest).

inputs:
goreleaser-version:
description: Version of GoReleaser to install (check latest from https://github.com/goreleaser/goreleaser/releases)
required: false
default: "2.18.2"

runs:
using: "composite"
steps:
- name: Install GoReleaser
shell: bash
env:
GORELEASER_VERSION: ${{ inputs.goreleaser-version }}
GORELEASER_TARBALL: goreleaser_Linux_x86_64.tar.gz
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
BASE_URL="https://github.com/goreleaser/goreleaser/releases/download/v${GORELEASER_VERSION}"

echo "Downloading GoReleaser binary and checksums..."
curl -sSL -O "${BASE_URL}/${GORELEASER_TARBALL}"
curl -sSL -O "${BASE_URL}/checksums.txt"

echo "Verifying checksum..."
grep " ${GORELEASER_TARBALL}$" checksums.txt | sha256sum --check --status

if [ $? -eq 0 ]; then
echo "Verification successful!"
tar -xzf "${GORELEASER_TARBALL}" goreleaser
chmod +x goreleaser
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv goreleaser "${RUNNER_TEMP}/bin/goreleaser"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
rm -f "${GORELEASER_TARBALL}" checksums.txt
goreleaser --version
else
echo "ERROR: Checksum verification failed!" >&2
exit 1
fi
8 changes: 7 additions & 1 deletion actions/syft/generate-sbom/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ runs:
SYFT_TARBALL: syft_${{ inputs.syft-version }}_linux_amd64.tar.gz
SYFT_CHECKSUMS: syft_${{ inputs.syft-version }}_checksums.txt
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
BASE_URL="https://github.com/anchore/syft/releases/download/v${SYFT_VERSION}"

echo "Downloading Syft binary and checksums..."
Expand All @@ -58,7 +60,11 @@ runs:
echo "Verification successful!"
tar -xzf "${SYFT_TARBALL}" syft
chmod +x syft
sudo mv syft /usr/local/bin/syft
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv syft "${RUNNER_TEMP}/bin/syft"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
rm -f "${SYFT_TARBALL}" "${SYFT_CHECKSUMS}"
syft version
else
Expand Down
8 changes: 7 additions & 1 deletion actions/terraform/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ runs:
TERRAFORM_ZIP: terraform_${{ inputs.terraform-version }}_linux_amd64.zip
TERRAFORM_SHA256SUMS: terraform_${{ inputs.terraform-version }}_SHA256SUMS
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
BASE_URL="https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}"

echo "Downloading Terraform binary and checksums..."
Expand All @@ -33,7 +35,11 @@ runs:
echo "Verification successful!"
unzip -o "${TERRAFORM_ZIP}"
chmod +x terraform
sudo mv terraform /usr/local/bin/terraform
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv terraform "${RUNNER_TEMP}/bin/terraform"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
rm -f "${TERRAFORM_ZIP}" "${TERRAFORM_SHA256SUMS}"
terraform version
else
Expand Down
8 changes: 7 additions & 1 deletion actions/tflint/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ runs:
TFLINT_VERSION: ${{ inputs.tflint-version }}
TFLINT_ZIP: tflint_linux_amd64.zip
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
BASE_URL="https://github.com/terraform-linters/tflint/releases/download/${TFLINT_VERSION}"

echo "Downloading TFLint binary and checksums..."
Expand All @@ -32,7 +34,11 @@ runs:
echo "Verification successful!"
unzip -o "${TFLINT_ZIP}"
chmod +x tflint
sudo mv tflint /usr/local/bin/tflint
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv tflint "${RUNNER_TEMP}/bin/tflint"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
rm -f "${TFLINT_ZIP}" checksums.txt
tflint --version
else
Expand Down
8 changes: 7 additions & 1 deletion actions/trivy/scan/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ runs:
TRIVY_TARBALL: trivy_${{ inputs.trivy-version }}_Linux-64bit.tar.gz
TRIVY_CHECKSUMS: trivy_${{ inputs.trivy-version }}_checksums.txt
run: |
# Downloaded into a directory of its own, since the repository may hold a file or a directory named like the binary.
cd "$(mktemp -d)"
BASE_URL="https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}"

echo "Downloading Trivy binary and checksums..."
Expand All @@ -65,7 +67,11 @@ runs:
echo "Verification successful!"
tar -xzf "${TRIVY_TARBALL}" trivy
chmod +x trivy
sudo mv trivy /usr/local/bin/trivy
# Installed where the job owns the directory, so neither root nor sudo is needed, on a hosted runner or in a container.
mkdir -p "${RUNNER_TEMP}/bin"
mv trivy "${RUNNER_TEMP}/bin/trivy"
echo "${RUNNER_TEMP}/bin" >> "$GITHUB_PATH"
export PATH="${RUNNER_TEMP}/bin:$PATH"
rm -f "${TRIVY_TARBALL}" "${TRIVY_CHECKSUMS}"
trivy version
else
Expand Down
Loading