Repository containing reusable GitHub Actions workflows for public repositories.
This repository provides the following reusable workflows:
- Slither Analysis - Static analysis for Solidity smart contracts
- Zizmor Workflow Scanner - Security scanner for GitHub Actions workflows
- Action Lint - Validation and linting for GitHub Actions workflows
- Documentation Update - Automatic README updates on release
- Validate PR Label - Ensures semantic versioning labels on pull requests
- Semantic Versioning - Creates and pushes version tags after a merged PR
- Checkov - Terraform static analysis and secrets scanning with Checkov
- Infracost Check - Terraform cost estimates on pull requests
-
Create a workflow in your repository (e.g.,
.github/workflows/security-checks.yaml) -
Reference the workflows from this repository:
name: Security Checks
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
zizmor:
uses: vechain/github-actions-public/.github/workflows/scan-workflows.yaml@f54f69d33344b241b5ec901d3d5e1b02d44a1b96
secrets:
ZIZMOR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
actionlint:
uses: vechain/github-actions-public/.github/workflows/action-lint.yaml@f54f69d33344b241b5ec901d3d5e1b02d44a1b96
⚠️ IMPORTANT: For production use, it's highly recommended to pin to a specific commit SHA or release tag instead of@mainto ensure consistency and avoid potential issues.
Static analysis tool for Solidity smart contracts that detects vulnerabilities and code quality issues.
Workflow: .github/workflows/slither.yaml
| Input | Required | Default | Description |
|---|---|---|---|
target |
false | packages/contracts/ |
Directory containing Solidity contracts |
solc-version |
false | 0.8.20 |
Solidity compiler version |
fail-on |
false | none |
Fail on issue level (none, high, medium, low) |
slither-args |
false | See workflow | Additional Slither arguments |
sarif-file |
false | slither-results.sarif |
Path for SARIF output file |
skip-change-detection |
false | false |
Skip internal change detection |
env-vars |
false | {} |
Additional environment variables (JSON format) |
cache |
false | yarn |
Package manager for caching (npm, yarn, pnpm) |
compile-command |
false | skip |
Command to compile contracts |
ignore-compile |
false | false |
Use existing artifacts without compilation |
| Secret | Required | Description |
|---|---|---|
MNEMONIC |
false | Mnemonic for local environment (dummy value used if not provided) |
TESTNET_STAGING_MNEMONIC |
false | Mnemonic for testnet staging |
GALACTICA_TEST_MNEMONIC |
false | Mnemonic for Galactica test |
VECHAIN_URL_DEVNET |
false | VeChain devnet URL |
| Output | Description |
|---|---|
compilation-status |
Status of contract compilation |
slither-status |
Status of Slither analysis |
comment-status |
Status of PR comment posting |
sarif-file |
Path to generated SARIF file |
overall-status |
Overall workflow status |
Basic usage:
slither:
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0Custom configuration:
slither:
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0
with:
target: 'contracts/'
solc-version: '0.8.19'
fail-on: 'high'
slither-args: '--exclude-informational --exclude-optimization'
cache: 'npm'
compile-command: 'npm run build:contracts'With external change detection:
check-changes:
runs-on: ubuntu-latest
outputs:
contracts-changed: ${{ steps.changes.outputs.contracts }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
contracts:
- 'contracts/**'
slither:
needs: check-changes
if: needs.check-changes.outputs.contracts-changed == 'true'
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0
with:
target: 'contracts/'
skip-change-detection: trueWith custom environment variables:
slither:
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0
with:
target: 'contracts/'
env-vars: '{"NODE_ENV": "testing", "DEBUG_MODE": "false"}'
secrets:
MNEMONIC: ${{ secrets.MNEMONIC }}
VECHAIN_URL_DEVNET: ${{ secrets.VECHAIN_URL_DEVNET }}Security scanner for GitHub Actions workflows that detects security issues and misconfigurations using ReviewDog for PR feedback.
Workflow: .github/workflows/scan-workflows.yaml
| Input | Required | Default | Description |
|---|---|---|---|
persona |
false | regular |
Scan persona (regular, pedantic, auditor) |
min_severity |
false | medium |
Minimum severity to report (low, medium, high) |
min_confidence |
false | high |
Minimum confidence to report (informational, low, medium, high) |
| Secret | Required | Description |
|---|---|---|
ZIZMOR_TOKEN |
true | Personal Access Token for zizmor (can use GITHUB_TOKEN) |
Basic usage:
zizmor:
uses: vechain/github-actions-public/.github/workflows/scan-workflows.yaml@v.2.3.0
secrets:
ZIZMOR_TOKEN: ${{ secrets.GITHUB_TOKEN }}Custom configuration:
zizmor:
uses: vechain/github-actions-public/.github/workflows/scan-workflows.yaml@v.2.3.0
with:
persona: 'auditor'
min_severity: 'high'
min_confidence: 'medium'
secrets:
ZIZMOR_TOKEN: ${{ secrets.GITHUB_TOKEN }}Features:
- Scans GitHub workflows with Zizmor for security issues
- Posts results as PR reviews via ReviewDog on pull requests
- Publishes GitHub Checks on non-PR events
- Generates SARIF output for code scanning integration
Validates GitHub Actions workflow files for syntax errors, best practices, and common issues.
Workflow: .github/workflows/action-lint.yaml
Basic usage:
actionlint:
uses: vechain/github-actions-public/.github/workflows/action-lint.yaml@v.2.3.0On pull requests only:
name: Workflow Validation
on:
pull_request:
jobs:
actionlint:
uses: vechain/github-actions-public/.github/workflows/action-lint.yaml@v.2.3.0Features:
- Validates workflow syntax and structure
- Checks for common mistakes and anti-patterns
- Provides detailed error messages with file/line information
- Integrates with GitHub's problem matcher for inline annotations
Automatically updates README.md with new release tags and commit SHAs when a release is published.
Workflow: .github/workflows/doc-update.yaml
This workflow is triggered automatically on release events. To use it:
- Add the workflow to your repository
- Ensure your README.md contains version references (e.g.,
v.2.3.0and commit SHAs) - Create a new release
Workflow trigger:
name: Update Documentation
on:
release:
types: [published]
jobs:
update-docs:
uses: vechain/github-actions-public/.github/workflows/doc-update.yaml@v.2.3.0Features:
- Automatically updates version tags in README.md
- Updates commit SHAs to match new release
- Attempts direct push to main branch
- Creates PR if direct push fails (branch protection enabled)
- Provides detailed summary of changes
Ensures every pull request has exactly one of the semantic versioning labels (increment:major, increment:minor, increment:patch) before merge. Optionally fails if the label is missing, or applies a default label (by default increment:patch) via the GitHub API.
Workflow: .github/workflows/validate-pr-label.yaml
| Input | Required | Default | Description |
|---|---|---|---|
FAIL_IF_MISSING_LABEL |
false | false |
If true, the job fails when no increment label is present (forces manual labeling). |
DEFAULT_LABEL |
false | increment:patch |
Label applied automatically when none is present and FAIL_IF_MISSING_LABEL is false. |
Call this job from a workflow that runs on pull_request. The calling workflow needs permission to add labels (for example pull-requests: write).
Basic usage (auto-apply patch if missing):
name: PR labels
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
jobs:
validate-label:
permissions:
contents: read
pull-requests: write
uses: vechain/github-actions-public/.github/workflows/validate-pr-label.yaml@v.2.3.0Require explicit increment label (no auto-apply):
jobs:
validate-label:
permissions:
contents: read
pull-requests: read
uses: vechain/github-actions-public/.github/workflows/validate-pr-label.yaml@v.2.3.0
with:
FAIL_IF_MISSING_LABEL: trueFeatures:
- Validates presence of
increment:major,increment:minor, orincrement:patch - Optional automatic default label when validation-only mode is off
- Pairs with Semantic Versioning, which reads the same labels after merge
After a pull request is merged, creates a new Git tag in the form v.MAJOR.MINOR.PATCH and pushes it to the repository. The bump level is derived from PR labels (increment:major, increment:minor, increment:patch); if none match, patch is used. The workflow name in the YAML file is “Codebase Versioning”.
Workflow: .github/workflows/semantic-versioning.yaml
| Secret | Required | Description |
|---|---|---|
DEPLOY_KEY |
true | SSH private key with permission to push tags to the repository (configure the matching deploy key in repo settings). |
Invoke from a workflow triggered when a PR is merged (for example pull_request with types: [closed]). The reusable workflow skips work unless github.event.pull_request.merged == true.
Example:
name: Version tag on merge
on:
pull_request:
types: [closed]
jobs:
tag-release:
if: github.event.pull_request.merged == true
uses: vechain/github-actions-public/.github/workflows/semantic-versioning.yaml@v.2.3.0
secrets:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}Features:
- Reads increment intent from the same
increment:*labels as Validate PR Label - Skips tagging if the current
HEADalready matches the latestv.*tag - Annotated tag message includes the PR title
Runs Checkov (via checkov-action) on the repository for Terraform (framework: terraform), with an optional local config file .checkov.yaml when present. Publishes CLI output and JSON, and uploads results.json as a workflow artifact (including when the scan step fails, if the job is still created).
Workflow: .github/workflows/checkov.yaml
| Input | Required | Default | Description |
|---|---|---|---|
skip_path |
false | (empty) | Path pattern(s) to skip (Checkov skip_path; comma-separated as supported by Checkov). |
soft_fail |
false | true |
Same behavior as the original workflow when omitted. Set to false to fail the job when Checkov reports failed checks. |
external_checks_dirs is fixed to ./checkov-external-checks (same as the first published version) so existing consumers keep identical Checkov CLI arguments.
jobs:
checkov:
permissions:
contents: read
actions: write # required for the JSON artifact upload
uses: vechain/github-actions-public/.github/workflows/checkov.yaml@v.2.3.0
# Optional:
# with:
# skip_path: '^examples/'
# soft_fail: falseFeatures:
- Scans the repo root (
directory: .) for Terraform; optional.checkov.yamlwhen committed - Custom checks directory
./checkov-external-checks(same fixed path as always) - Secret scanning across files (
enable_secrets_scan_all_files) — review findings carefully for false positives - Artifact
scan-resultscontainsresults.json
Runs Infracost on pull requests: compares a baseline cost (merge base) with the PR branch, then posts a summary comment on the PR. Intended for repositories that use Terraform (.tf, .tfvars, .hcl). Supports private Terraform modules via an SSH deploy key.
Workflow: .github/workflows/infracost.yaml
| Input | Required | Default | Description |
|---|---|---|---|
run-on-tf-changes-only |
false | true |
If true, skip the cost job unless Terraform-related files changed (via path filters). |
comment_behavior |
false | update |
How to post PR comments: update, new, hide-and-new, or delete-and-new (docs). Invalid values fall back to update. |
root_path |
false | . |
Directory passed to Infracost --path. |
exclude_path |
false | — | Optional --exclude-path for Infracost. |
terraform_var_files |
false | — | Comma-separated tfvars paths (e.g. vars/dev.tfvars,vars/common.tfvars). |
terraform_vars |
false | — | Comma-separated key=value pairs for --terraform-var. |
| Secret | Required | Description |
|---|---|---|
INFRACOST_API_KEY |
true | Infracost Cloud API key. |
TERRAFORM_SSH_KEY |
true | SSH private key used to clone private Terraform modules over SSH (git@github.com:...). Configure the matching deploy key or user key as appropriate. |
The workflow file only references secret names; values stay in GitHub Actions secrets and are not in the repository. GitHub masks registered secrets in job logs (avoid enabling debug logging that prints environment dumps). For public repos, workflows triggered by pull_request from forks do not receive upstream repository secrets, so outside contributors cannot run jobs that use these keys against your secrets.
Call only from workflows triggered by pull_request (the reusable workflow expects github.event.pull_request). The cost job runs on opened and synchronize; a separate job detects Terraform file changes when run-on-tf-changes-only is enabled.
Example:
name: Infracost
on:
pull_request:
branches: [main]
jobs:
infracost:
permissions:
contents: read
pull-requests: write
uses: vechain/github-actions-public/.github/workflows/infracost.yaml@v.2.3.0
secrets:
INFRACOST_API_KEY: ${{ secrets.INFRACOST_API_KEY }}
TERRAFORM_SSH_KEY: ${{ secrets.TERRAFORM_SSH_KEY }}
with:
root_path: infra
run-on-tf-changes-only: true
comment_behavior: updateFeatures:
- Baseline checkout on the PR base ref, then checkout of the PR head for
infracost diff - Optional skip when no Terraform paths changed (
dorny/paths-filter) persist-credentials: falseon checkout; GitHub token used only for posting the Infracost comment
Always pin workflows to specific versions for security and stability:
# ✅ Good - pinned to specific SHA
uses: vechain/github-actions-public/.github/workflows/slither.yaml@a1b2c3d4...
# ✅ Good - pinned to release tag
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0
# ⚠️ Avoid - tracks main branch (unpredictable)
uses: vechain/github-actions-public/.github/workflows/slither.yaml@mainConfigure minimal required permissions for each workflow:
jobs:
security-checks:
permissions:
contents: read
security-events: write
pull-requests: write
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0Use GitHub secrets for sensitive data:
jobs:
slither:
uses: vechain/github-actions-public/.github/workflows/slither.yaml@v.2.3.0
secrets:
MNEMONIC: ${{ secrets.MNEMONIC }}
# ❌ Never hardcode secrets in workflowsContributions are welcome! Please ensure that:
- All workflows are tested before submission
- Documentation is updated for new features
- Workflows follow security best practices
- Changes are backwards compatible when possible
This project is licensed under the LICENSE.
For issues, questions, or feature requests, please open an issue in this repository.