Skip to content

ci: add CI workflows and pre-commit hooks - #2

Merged
thiras merged 2 commits into
mainfrom
feat/ci-and-pre-commit
Jun 3, 2026
Merged

thiras merged 2 commits into
mainfrom
feat/ci-and-pre-commit

Conversation

@thiras

@thiras thiras commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

What

Adds a two-layer quality gate to the DevOps monorepo, which previously had no CI and no pre-commit config.

Local — .pre-commit-config.yaml

Hygiene, shellcheck, yamllint (reuses ansible/.yamllint), and markdownlint. ansible-lint is an opt-in manual hook (it needs Galaxy collections installed). Install with make hooks.

CI — .github/workflows/

  • ci.yml — a path-filtered pipeline: pre-commit, ansible-lint + playbook --syntax-check, KICS Ansible security scan, and actionlint. Bash-only PRs skip the Ansible jobs.
  • molecule.yml — blocking containerised converge/verify, scoped to ansible/** changes.

Supporting files

Root Makefile (hooks/lint/lint-ansible/security/molecule), CONTRIBUTING.md, .shellcheckrc, .markdownlint-cli2.yaml, .github/dependabot.yml, and a kics-results/ gitignore entry.

Supply-chain hardening

  • All third-party actions pinned to full commit SHAs (version-commented); Dependabot bumps them weekly.
  • KICS uses the official Checkmarx/kics-github-action, pinned to its post-remediation hardened HEAD by SHA. The March 2026 TeamPCP tag-hijack (CISA KEV) has been remediated; the v2.1.20 tag predates the April base-image digest-pinning, so Dependabot is told not to bump it.
  • There is no dedicated secret-scanner in the pipeline (removed by request) — secrets stay out by design (.gitignore + templates only); enable GitHub push protection if desired.

Note on the bash changes

services/anvil-devnet/bin/{lib.sh,install.sh} were made genuinely shellcheck-clean (proper source/library directives) so the new shellcheck gate passes on day one — they were not clean before.

Verified locally

pre-commit run --all-files (13 hooks), actionlint, ansible-lint + syntax-check, and KICS (0 HIGH → exit 0) all pass.

Follow-up (manual GitHub settings, not in this PR)

Mark the ci.yml jobs and molecule as required status checks in branch protection once proven.

🤖 Generated with Claude Code

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) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 3, 2026 19:16

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces local development hygiene and CI configurations, including pre-commit hooks, a markdownlint configuration, a repository-wide ShellCheck configuration, a central Makefile, and a CONTRIBUTING guide detailing supply-chain pinning rules. Feedback on these changes suggests running the KICS Docker container in the Makefile with the host user's UID/GID to avoid permission issues with generated files on Linux, and explicitly exporting the required variable in lib.sh instead of globally toggling set -a.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread services/anvil-devnet/bin/lib.sh Outdated
Comment thread Makefile Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces baseline contributor hygiene and automated quality gates for this DevOps monorepo by adding pre-commit configuration, GitHub Actions CI workflows, and supporting documentation/Make targets to run linting, Ansible validation, Molecule testing, and KICS security scanning.

Changes:

  • Add local pre-commit hooks for formatting/linting (shellcheck, yamllint for ansible/, markdownlint, and general hygiene).
  • Add GitHub Actions workflows for a path-filtered CI pipeline (pre-commit, Ansible lint + syntax-check, KICS scan, actionlint) plus a separate Molecule workflow gated on ansible/** changes.
  • Add supporting repo docs/config (Makefile targets, contributing guide, lint configs, dependabot, and KICS results ignore).

Reviewed changes

Copilot reviewed 8 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
services/anvil-devnet/bin/lib.sh Adjusts shellcheck-related directives and env sourcing to be lint-clean under the new gates.
services/anvil-devnet/bin/install.sh Adds a targeted shellcheck suppression to keep the script clean under CI/pre-commit.
Makefile Adds convenience targets to run hooks/lint/ansible lint/KICS/molecule from repo root.
CONTRIBUTING.md Documents the new local + CI quality gates and supply-chain pinning approach.
.shellcheckrc Establishes repo-wide shellcheck configuration suitable for the ops script layout.
.pre-commit-config.yaml Defines local pre-commit hooks and scopes YAML linting to ansible/.
.markdownlint-cli2.yaml Configures a relaxed markdownlint ruleset to fit existing docs while catching structural issues.
.gitignore Ignores generated KICS output directory.
.github/workflows/molecule.yml Adds an ansible/**-scoped Molecule workflow to run converge/verify in CI.
.github/workflows/ci.yml Adds path-filtered CI jobs for pre-commit, Ansible lint/syntax-check, KICS, and actionlint with SHA-pinned actions.
.github/dependabot.yml Adds Dependabot config to keep SHA-pinned GitHub Actions dependencies updated (with an explicit ignore for KICS action pin).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yml Outdated
- 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) <noreply@anthropic.com>
@thiras
thiras merged commit d879b30 into main Jun 3, 2026
6 checks passed
@thiras
thiras deleted the feat/ci-and-pre-commit branch June 3, 2026 19:24
thiras added a commit that referenced this pull request Jun 7, 2026
* feat(anvil): expose devnet RPC over public HTTPS via Caddy

The anvil devnet was unreachable off-host: rpc-dev.decdn.org A-records
straight to the droplet, but nftables default-deny opened no HTTP hole
(Caddy bound 127.0.0.1:8080) and the documented Cloudflare tunnel was
never stood up. A firewall change alone is a no-op since Caddy is
loopback-bound, so this moves Caddy's listener public too.

- Add caddy_public toggle (default true): Caddy serves rpc_hostname on
  443 with auto-TLS (Let's Encrypt) + per-dev basic auth, reverse-proxying
  to the loopback anvil. Set false for the old loopback plain-HTTP mode
  (dev/CI or behind a tunnel).
- Open tcp/80+443 for the anvil_devnet group via baseline_extra_inbound
  (new inventory/group_vars/anvil_devnet.yml), the same idiom decdn_nodes
  uses for udp/4433. 80 carries ACME HTTP-01 + the http->https redirect.
- Pin molecule to caddy_public: false so CI keeps asserting the loopback
  bind and avoids a doomed public-ACME attempt in-container.
- anvil itself stays loopback; only the auth-terminating Caddy proxy faces
  the internet. Update hard-rule #2, README, and CLAUDE.md accordingly.

Verified: ansible-lint (production), molecule (converge/idempotence/verify),
KICS (0 high/critical), galaxy build/check, and `make check-anvil` dry-run
(shows the exact nftables + Caddyfile diffs). Live deploy intentionally
deferred to an operator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(caddy): guard caddy_acme_email with default('') in Caddyfile

`caddy_acme_email | length > 0` errors under StrictUndefined or when the
var is set to null/None in group_vars. `| default('')` absorbs both and
relies on empty-string falsiness — verified across empty/None/set/undefined.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants