From 3314f5406e50f9cac713253b402fde8c474390d7 Mon Sep 17 00:00:00 2001 From: Ant Somers Date: Wed, 3 Jun 2026 22:15:43 +0300 Subject: [PATCH 1/2] ci: add CI workflows and pre-commit hooks Introduce a two-layer quality gate for the DevOps monorepo, which had no CI and no pre-commit config. Local (.pre-commit-config.yaml): hygiene, shellcheck, yamllint (reusing ansible/.yamllint), and markdownlint. ansible-lint is an opt-in manual hook. CI (.github/workflows/): - ci.yml: path-filtered pre-commit, ansible-lint + playbook syntax-check, KICS Ansible security scan, and actionlint. - molecule.yml: blocking containerised converge/verify on ansible/** changes. Supply-chain hardening: - Third-party actions pinned to full commit SHAs (version-commented); Dependabot bumps them weekly (.github/dependabot.yml). - KICS uses the official Checkmarx/kics-github-action pinned to its post-remediation hardened HEAD (the March 2026 TeamPCP hijack was remediated; the v2.1.20 tag predates the April base-image hardening, so Dependabot is told not to bump it). Supporting files: root Makefile (hooks/lint/security/molecule), CONTRIBUTING.md, .shellcheckrc, .markdownlint-cli2.yaml, and a kics-results/ gitignore entry. Make the existing anvil-devnet bash scripts shellcheck-clean (proper source and library directives) so the new shellcheck gate passes. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/dependabot.yml | 31 ++++++ .github/workflows/ci.yml | 150 +++++++++++++++++++++++++++ .github/workflows/molecule.yml | 39 +++++++ .gitignore | 3 + .markdownlint-cli2.yaml | 22 ++++ .pre-commit-config.yaml | 89 ++++++++++++++++ .shellcheckrc | 7 ++ CONTRIBUTING.md | 58 +++++++++++ Makefile | 34 ++++++ services/anvil-devnet/bin/install.sh | 2 + services/anvil-devnet/bin/lib.sh | 8 +- 11 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/molecule.yml create mode 100644 .markdownlint-cli2.yaml create mode 100644 .pre-commit-config.yaml create mode 100644 .shellcheckrc create mode 100644 CONTRIBUTING.md create mode 100644 Makefile diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..bfaa5a0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,31 @@ +--- +# Dependabot — keeps the SHA-pinned GitHub Actions current (it rewrites +# `uses: owner/repo@ # vX.Y.Z` to the new sha + version comment). +# +# github-actions is the only applicable ecosystem: the repo has no pip/npm/etc. +# manifests, and `ansible/requirements.yml` is Ansible Galaxy, which Dependabot +# does not support. +# +# NOT covered here, bump manually: +# - the KICS engine image digest in the Makefile — see CONTRIBUTING.md +# - the Galaxy collections in ansible/requirements.yml +# - pre-commit hook revs — run `pre-commit autoupdate` +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + commit-message: + prefix: ci # conventional commits -> "ci(deps): ..." + include: scope + groups: + actions: + patterns: ["*"] + ignore: + # Pinned to the post-remediation hardened HEAD (see ci.yml). The newest + # RELEASE tag (v2.1.20) points at an older commit that predates the April + # 2026 base-image digest-pinning, so an automated bump would DOWNGRADE + # security. Re-pin manually only after verifying a newer clean commit/tag. + - dependency-name: "Checkmarx/kics-github-action" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e4ea7c7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,150 @@ +--- +name: CI + +on: + push: + branches: [main] + pull_request: + +# Least privilege by default; jobs widen only what they need. +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +# Third-party actions are pinned to a full commit SHA (a re-pointed tag can ship +# malicious code — cf. the March 2026 KICS action compromise). The trailing +# comment records the human-readable version; .github/dependabot.yml bumps them. +jobs: + # Detect which units changed so the heavy Ansible jobs skip bash-only PRs. + changes: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + ansible: ${{ steps.filter.outputs.ansible }} + services: ${{ steps.filter.outputs.services }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 + id: filter + with: + filters: | + ansible: + - 'ansible/**' + services: + - 'services/**' + + # Fast, repo-wide gate: hygiene, secrets, shellcheck, yamllint, markdown. + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: '3.12' + - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 + + # Ansible style + best-practice + the production-profile SECURITY rules, + # plus a syntax-check of every playbook. Runs only when ansible/ changed. + ansible-lint: + needs: changes + if: needs.changes.outputs.ansible == 'true' + runs-on: ubuntu-latest + defaults: + run: + working-directory: ansible + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: '3.12' + - name: Install Ansible tooling + run: python -m pip install --upgrade ansible ansible-lint yamllint + - name: Install Galaxy collections + run: make deps # must precede lint/syntax-check + - name: Lint (yamllint + ansible-lint) + run: make lint + - name: Syntax-check playbooks + # Dummy inventory: the real inventory/hosts.yml is git-ignored, and + # --syntax-check only parses, it never connects. + run: | + for p in playbooks/site.yml playbooks/anvil.yml playbooks/add-dev-user.yml; do + echo "::group::syntax-check $p" + ansible-playbook "$p" --syntax-check -i localhost, + echo "::endgroup::" + done + + # Dedicated IaC security scan of the Ansible tree via the official KICS action. + # KICS severities are HIGH/MEDIUM/LOW/INFO (no "critical"); we gate on HIGH. + # + # SUPPLY-CHAIN NOTE: this action's git tags were hijacked in the March 2026 + # TeamPCP attack (CISA KEV). It has since been remediated — tags restored to + # their legitimate pre-hijack commits and explicit hardening applied (base + # images digest-pinned, workflows SHA-pinned, StepSecurity best practices). We + # pin to the post-remediation hardened HEAD by SHA; the `v2.1.20` *tag* points + # at the older Mar-04 commit that predates the April base-image digest-pinning, + # so we deliberately do NOT use the tag (and Dependabot is told not to bump it + # — see .github/dependabot.yml). Re-verify the SHA before any change. + kics: + needs: changes + if: needs.changes.outputs.ansible == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: KICS Ansible security scan (fail on HIGH) + # master @ 2026-05-22 "[StepSecurity] Apply security best practices (#157)" + uses: Checkmarx/kics-github-action@7117906d8779ecaf5180f34c4931a774f10d7625 + with: + path: ansible + platform_type: Ansible + exclude_paths: ansible/collections + fail_on: high + output_formats: json,sarif + output_path: kics-results + enable_jobs_summary: true + - name: Upload KICS results + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: kics-results + path: kics-results/ + if-no-files-found: ignore + # If GitHub Advanced Security is enabled on this private repo, surface KICS + # findings in the Security tab by un-commenting the block below (add + # `security-events: write` to this job's permissions): + # - name: Upload SARIF to code scanning + # if: always() + # uses: github/codeql-action/upload-sarif@d77b13a0df3134d64a457ea9003f600b09fa1c8a # v3.36.1 + # with: + # sarif_file: kics-results/results.sarif + + # Lint the workflow files themselves. + actionlint: + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: reviewdog/action-actionlint@6fb7acc99f4a1008869fa8a0f09cfca740837d9d # v1.72.0 + with: + reporter: github-check + fail_on_error: true + + # Solidity (forge fmt + build) self-activates once real .sol sources land: + # solidity: + # needs: changes + # if: needs.changes.outputs.services == 'true' && hashFiles('services/anvil-devnet/contracts/src/**/*.sol') != '' + # runs-on: ubuntu-latest + # defaults: + # run: + # working-directory: services/anvil-devnet/contracts + # steps: + # - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + # - uses: foundry-rs/foundry-toolchain@c7450ba673e133f5ee30098b3b54f444d3a2ca2d # v1.8.0 + # - run: forge fmt --check + # - run: forge build --sizes diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml new file mode 100644 index 0000000..d4dd80b --- /dev/null +++ b/.github/workflows/molecule.yml @@ -0,0 +1,39 @@ +--- +name: Molecule + +# Containerised converge + idempotence + verify for the anvil/caddy roles. +# Heavy (privileged systemd Docker container) — scoped to ansible/ changes and +# blocking. Mark it a required status check in branch protection once proven. +on: + pull_request: + paths: ['ansible/**'] + push: + branches: [main] + paths: ['ansible/**'] + +permissions: + contents: read + +concurrency: + group: molecule-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + molecule: + runs-on: ubuntu-latest # Docker is preinstalled + defaults: + run: + working-directory: ansible + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: '3.12' + - name: Install molecule + Ansible + run: | + python -m pip install --upgrade \ + molecule "molecule-plugins[docker]" ansible ansible-lint docker + - name: Install Galaxy collections + run: make deps + - name: molecule test + run: molecule test diff --git a/.gitignore b/.gitignore index b35fb5d..db0cc4b 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ # Local, per-developer Claude Code settings (not shared) .claude/settings.local.json + +# KICS security-scan output (`make security`; CI uploads it as an artifact) +kics-results/ diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml new file mode 100644 index 0000000..6dbc6bf --- /dev/null +++ b/.markdownlint-cli2.yaml @@ -0,0 +1,22 @@ +# markdownlint-cli2 config — relaxed ruleset so the existing docs pass while +# still catching genuine structural issues (broken links, empty/duplicate +# headings, multiple H1s, …) in new Markdown. The disabled rules below are +# purely stylistic or fire pervasively on the current docs; re-enable and fix +# incrementally if the team wants stricter formatting. +config: + MD013: false # line length — prose/tables run long here + MD033: false # inline HTML — allowed in docs + MD041: false # first line need not be a top-level heading + MD040: false # bare code fences (ASCII trees) are fine + MD031: false # blank lines around fences — pervasive in docs + MD022: false # blank lines around headings — pervasive in docs + MD049: false # emphasis style (underscore vs asterisk) — stylistic + MD060: false # table pipe spacing/alignment — finicky, opinionated + MD004: false # unordered list marker style (-, +, *) — stylistic + MD024: + siblings_only: true # duplicate headings only flagged within a section + +# Vendored collection docs are excluded at the pre-commit layer too. +ignores: + - "ansible/collections/**" + - "**/node_modules/**" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..2ba7b17 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,89 @@ +--- +# Pre-commit hooks for the deCDN DevOps monorepo. +# +# pip install pre-commit && make hooks # one-time install +# make lint # run on all files +# +# Heavier Ansible checks (ansible-lint, syntax-check, KICS security scan, +# molecule) run in CI only — see .github/workflows/. ansible-lint's production +# profile already carries the Ansible security rules; this file is the fast +# local gate (hygiene, shellcheck, yamllint, markdown). +minimum_pre_commit_version: "3.5.0" +default_install_hook_types: [pre-commit] + +# Vendored / generated trees only. +exclude: >- + (?x)^( + ansible/collections/| + ansible/\.ansible/| + services/anvil-devnet/contracts/(out|cache|broadcast)/ + ) + +repos: + # ── Generic hygiene ──────────────────────────────────────────────────────── + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] # keep markdown hard line breaks + - id: end-of-file-fixer + - id: check-merge-conflict + - id: check-added-large-files + args: [--maxkb=512] + - id: check-executables-have-shebangs + - id: check-shebang-scripts-are-executable + # Jinja2 templates render files that carry a shebang (e.g. nftables.conf + # starts with `#!/usr/sbin/nft -f`); the template itself isn't a script. + exclude: \.j2$ + - id: mixed-line-ending + args: [--fix=lf] + - id: check-yaml + args: [--unsafe] # tolerate custom/!vault tags; syntax check only + - id: check-json + - id: check-toml + + # ── Bash ─────────────────────────────────────────────────────────────────── + # Honors inline `# shellcheck` directives and the repo .shellcheckrc. + - repo: https://github.com/koalaman/shellcheck-precommit + rev: v0.11.0 + hooks: + - id: shellcheck + + # ── Markdown (relaxed ruleset; see .markdownlint-cli2.yaml) ──────────────── + - repo: https://github.com/DavidAnson/markdownlint-cli2 + rev: v0.22.1 + hooks: + - id: markdownlint-cli2 + + # ── YAML lint for the Ansible tree (reuses ansible/.yamllint) ────────────── + # Scoped to ansible/ so services/ YAML isn't held to Ansible style, and so it + # stays in lockstep with `make -C ansible lint`. *.yml.example templates don't + # match (they end in .example) and are skipped. + - repo: local + hooks: + - id: yamllint-ansible + name: yamllint (ansible/) + entry: yamllint -c ansible/.yamllint + language: python + additional_dependencies: ["yamllint==1.35.1"] + files: ^ansible/.*\.(ya?ml)$ + exclude: ^ansible/(collections|\.ansible)/ + + # Opt-in: full ansible-lint locally (needs `make -C ansible deps` first). + # pre-commit run ansible-lint --hook-stage manual + - id: ansible-lint + name: ansible-lint (manual — run `make -C ansible deps` first) + entry: bash -c 'make -C ansible lint' + language: system + pass_filenames: false + stages: [manual] + + # Solidity (forge fmt) self-activates once contracts/src has real .sol files: + # - repo: local + # hooks: + # - id: forge-fmt + # name: forge fmt --check + # entry: bash -c 'cd services/anvil-devnet/contracts && forge fmt --check' + # language: system + # files: ^services/anvil-devnet/contracts/.*\.sol$ + # exclude: \.example$ diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..e83a29a --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,7 @@ +# Repo-wide ShellCheck settings (read by the shellcheck pre-commit hook and CI). +# +# SC1091: the ops scripts `source ./lib.sh` at runtime relative to their own +# install dir; that file isn't resolvable during a static lint from the repo +# root, and following it isn't needed to check the callers. lib.sh itself is +# still linted directly. +disable=SC1091 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8fadabf --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contributing + +Two checks run on every change: **pre-commit** locally and **GitHub Actions** on +push / PR. The repo's #1 rule still stands — **never commit secrets** (see +[`CLAUDE.md`](CLAUDE.md)); secrets are generated on the target host and the repo +ships `*.example` templates only. There is no dedicated secret-scanner in the +pipeline — keep secrets out by design (and rely on GitHub's push protection). + +## One-time setup + +```bash +pip install pre-commit # or: pipx install pre-commit +make hooks # installs the git pre-commit hook +``` + +After this, every commit runs hygiene checks, `shellcheck`, `yamllint` (Ansible +tree), and `markdownlint`. + +## Useful targets (`make help`) + +| Target | What it does | +|--------|--------------| +| `make lint` | run all pre-commit hooks on every file (mirrors the CI `pre-commit` job) | +| `make lint-ansible` | install Galaxy collections + run `ansible-lint` (its production profile includes the Ansible security rules) | +| `make security` | KICS IaC security scan of `ansible/` (engine image; CI uses the official KICS action) | +| `make molecule` | containerised converge/verify of the anvil stack (needs Docker) | + +`ansible-lint` is **not** a per-commit hook (it needs the collections installed). +Run it on demand with `make lint-ansible`, or `pre-commit run ansible-lint --hook-stage manual`. + +## CI overview + +- **`ci.yml`** — `pre-commit`, `ansible-lint` + `kics` (on `ansible/**`), and + `actionlint`. Bash-only PRs skip the Ansible jobs. +- **`molecule.yml`** — runs on `ansible/**` changes; **blocking**. Add it as a + required status check in branch protection (Settings → Branches) once proven, + alongside the `ci.yml` jobs. + +## Supply-chain / pinning rules + +- **Third-party actions are pinned to a full commit SHA** with a version comment + — a mutable tag can be re-pointed to malicious code. +- **`Checkmarx/kics-github-action`** was hijacked in the March 2026 TeamPCP attack + (CISA KEV) and has since been remediated. It is pinned to the **post-remediation + hardened HEAD** by SHA — *not* a release tag, because the newest tag (`v2.1.20`) + predates the April hardening. Dependabot is told **not** to bump it + (`.github/dependabot.yml`); re-pin manually only after verifying a newer clean + commit. The KICS engine image used locally (`make security`) is pinned to the + pre-incident `v2.1.19` digest. +- **Dependabot** (`.github/dependabot.yml`) bumps the other action SHAs weekly. +- **Bump manually** (Dependabot can't): the `KICS_IMAGE` digest in the `Makefile`, + and the pre-commit hook revs via `pre-commit autoupdate`. + +## Solidity + +The `services/anvil-devnet/contracts/` Foundry project has no `.sol` sources yet. +The `forge fmt` pre-commit hook and the CI `solidity` job are present but +commented out; they self-activate once real sources land. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ae6cf93 --- /dev/null +++ b/Makefile @@ -0,0 +1,34 @@ +# Convenience targets for the deCDN DevOps monorepo. +# Run from the repo root. Ansible-specific work is delegated to ansible/Makefile. +.PHONY: help hooks lint lint-ansible security molecule +SHELL := /bin/bash + +# Local KICS runs use the engine image pinned by digest. CI runs the official +# Checkmarx/kics-github-action instead (a GitHub Action can't run outside CI); +# v2.1.19 (Jan 2026) predates the March/April 2026 supply-chain incidents. +KICS_IMAGE := checkmarx/kics:v2.1.19-alpine@sha256:e0335bf6e906183f9b3e243500cb055b7aeb72a7150841115fc45b6f14519732 + +help: ## list targets + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort \ + | awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}' + +hooks: ## install the pre-commit git hooks + pre-commit install + +lint: ## run all pre-commit hooks on all files (mirrors CI) + pre-commit run --all-files + +lint-ansible: ## full ansible-lint locally (installs collections first) + $(MAKE) -C ansible deps + $(MAKE) -C ansible lint + +security: ## KICS IaC security scan of ansible/ (CI runs the official action) + mkdir -p kics-results + docker run --rm -v "$(CURDIR):/repo" $(KICS_IMAGE) \ + scan --path /repo/ansible --type Ansible \ + --exclude-paths /repo/ansible/collections \ + --report-formats json --output-path /repo/kics-results \ + --no-progress --fail-on high + +molecule: ## containerised converge/verify of the anvil stack + $(MAKE) -C ansible molecule diff --git a/services/anvil-devnet/bin/install.sh b/services/anvil-devnet/bin/install.sh index 15cb20c..5c01bb7 100755 --- a/services/anvil-devnet/bin/install.sh +++ b/services/anvil-devnet/bin/install.sh @@ -65,6 +65,8 @@ fi # ── 5. cloudflared (official Cloudflare apt repo) ──────────────────────────── if ! command -v cloudflared >/dev/null 2>&1; then log "Installing cloudflared…" + # -m applies only to the deepest dir, which is all we create here. + # shellcheck disable=SC2174 mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \ > /usr/share/keyrings/cloudflare-main.gpg diff --git a/services/anvil-devnet/bin/lib.sh b/services/anvil-devnet/bin/lib.sh index bf2c3c3..81200b1 100755 --- a/services/anvil-devnet/bin/lib.sh +++ b/services/anvil-devnet/bin/lib.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash # Shared config + helpers for the anvil-devnet ops scripts. # Sourced by install.sh / bootstrap.sh / caddy-add-user.sh / deploy.sh / reset.sh. +# +# Most names below are configuration constants read by the scripts that source +# this file, so ShellCheck sees them as unused within lib.sh itself. +# shellcheck disable=SC2034 set -euo pipefail # --- Foundry ----------------------------------------------------------------- @@ -59,8 +63,10 @@ wait_for_rpc() { # Requires root (or the anvil user) because the file is mode 600. read_mnemonic() { [ -r "$ANVIL_ENV" ] || die "Cannot read ${ANVIL_ENV}. Run as root, after bootstrap.sh." + set -a # shellcheck disable=SC1090 - set -a; . "$ANVIL_ENV"; set +a + . "$ANVIL_ENV" + set +a [ -n "${ANVIL_MNEMONIC:-}" ] || die "ANVIL_MNEMONIC not set in ${ANVIL_ENV}." } From e3cc8e36ae6467868f6bb3aba0321ca373540424 Mon Sep 17 00:00:00 2001 From: Ant Somers Date: Wed, 3 Jun 2026 22:23:07 +0300 Subject: [PATCH 2/2] ci: address review feedback - ci.yml: drop stale "secrets" from the pre-commit job comment (no secret-scanning hook is configured). - lib.sh: export ANVIL_MNEMONIC explicitly instead of toggling `set -a` globally around the source (avoids exporting unintended vars). - Makefile: run the local KICS container as the host UID/GID so kics-results/ files aren't root-owned on rootful Docker. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 2 +- Makefile | 2 +- services/anvil-devnet/bin/lib.sh | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4ea7c7..6698770 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: services: - 'services/**' - # Fast, repo-wide gate: hygiene, secrets, shellcheck, yamllint, markdown. + # Fast, repo-wide gate: hygiene, shellcheck, yamllint, markdown. pre-commit: runs-on: ubuntu-latest steps: diff --git a/Makefile b/Makefile index ae6cf93..a5efdcb 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ lint-ansible: ## full ansible-lint locally (installs collections first) security: ## KICS IaC security scan of ansible/ (CI runs the official action) mkdir -p kics-results - docker run --rm -v "$(CURDIR):/repo" $(KICS_IMAGE) \ + docker run --rm --user $(shell id -u):$(shell id -g) -v "$(CURDIR):/repo" $(KICS_IMAGE) \ scan --path /repo/ansible --type Ansible \ --exclude-paths /repo/ansible/collections \ --report-formats json --output-path /repo/kics-results \ diff --git a/services/anvil-devnet/bin/lib.sh b/services/anvil-devnet/bin/lib.sh index 81200b1..cf17fec 100755 --- a/services/anvil-devnet/bin/lib.sh +++ b/services/anvil-devnet/bin/lib.sh @@ -63,10 +63,9 @@ wait_for_rpc() { # Requires root (or the anvil user) because the file is mode 600. read_mnemonic() { [ -r "$ANVIL_ENV" ] || die "Cannot read ${ANVIL_ENV}. Run as root, after bootstrap.sh." - set -a # shellcheck disable=SC1090 . "$ANVIL_ENV" - set +a + export ANVIL_MNEMONIC [ -n "${ANVIL_MNEMONIC:-}" ] || die "ANVIL_MNEMONIC not set in ${ANVIL_ENV}." }