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
71 changes: 11 additions & 60 deletions ansible/inventories/localhost/group_vars/all.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
---
# --pinned mode SSoT. Default is LATEST: hyperi_pinned is false, so every tool
# installs the newest release. `install.sh --pinned` sets hyperi_pinned=true (a
# -e extra var, highest precedence), and each retrofitted manual-binary task
# then fetches the exact tag below instead of /releases/latest.
# Every tool resolves its version at install time, so a run in four months
# installs what is current in four months.
#
# hyperi_versions MIRRORS hyperi-ci's config/versions.yaml `tools:` block, so a
# pinned local box matches CI exactly. `tools/ci/run-tests.sh` compares the two
# and fails on any disagreement, so this no longer relies on someone
# remembering; edit a version here and the test says which side is wrong.
# Manual binaries query `/releases/latest`. Cargo tools install unversioned. Go
# and rustup fetch the current version with the checksum published beside it.
#
# Pinning is by TAG, exactly as hyperi-ci does today -- a fetched release ASSET
# cannot be force-moved by a tag rewrite, but it is not yet digest-verified.
# SHA256-at-download is the planned hardening (tracked upstream as hyperi-ci
# #66); when it lands, add a `sha256:` per tool here and a `checksum:` on the
# get_url/unarchive. Tools absent from this map fall back to latest even in
# pinned mode (they carry no CI-parity pin to mirror).
hyperi_pinned: false
# What remains below is a selection rather than a version -- a Node LTS line,
# which NodeSource's signed repo then keeps patched.

# GitHub's anonymous release API allows 60 requests an hour PER IP, and a run
# selecting infrastructure plus a couple of languages spends a good fraction of
Expand All @@ -40,20 +31,6 @@ hyperi_github_headers: >-
hyperi_github_env: >-
{{ {'GITHUB_TOKEN': hyperi_github_token} if hyperi_github_token else {} }}

hyperi_versions:
alint: v0.14.1
gitleaks: v8.30.1
hadolint: v2.15.1
kubeconform: v0.8.0
kube-linter: v0.8.3
osv-scanner: v2.4.0
golangci-lint: v2.12.2
gosec: v2.28.0
govulncheck: v1.1.4
cargo-audit: v0.22.2
cargo-deny: 0.20.2
cargo-chef: v0.1.77

# ============================================================================
# Core component versions -- the ONE place to bump them
# ============================================================================
Expand All @@ -75,11 +52,12 @@ hyperi_versions:
# its own via `apt/dnf upgrade`, so only the MAJOR is pinned
# here -- there is no patch version to chase, and routine OS
# updates carry the tool forward for free.
# pinned artefact go, rustup, fnm. Upstream publishes no repo, so we pin an
# exact version (rung 3) and `hyperi-update` refreshes them.
# resolved artefact go, rustup, fnm. Upstream publishes no repo, so the role
# asks upstream for the current release when it runs and
# verifies the download against the checksum served with it.
#
# Bumping a major in a year is editing a number here. Nothing below is repeated
# in a role.
# Only the Node majors remain, because a major is a choice rather than a version
# to chase. Bumping one in a year is editing a number here.
hyperi_core_versions:
# Node n and n-1. n is installed system-wide from the NodeSource repo, so
# root, systemd units, semantic-release and CI all resolve the same node;
Expand All @@ -88,30 +66,3 @@ hyperi_core_versions:
# 26 and 24.
node_major: 24
node_major_previous: 22

# Go publishes tarballs only -- no apt/dnf repo exists -- so this is the
# pinned-artefact rung: exact version plus a SHA256 we hold, per arch. This
# is the hardening the `hyperi_versions` note above calls planned; for these
# two tools it is done.
# Floor is 1.26.6, which fixed 10 CVEs -- among them a remote DoS against any
# Go TLS server (CVE-2026-56862) and two sumdb flaws (CVE-2026-56864/56865)
# letting a hostile GOPROXY smuggle unauthenticated modules into the cache.
go: "1.26.7"
go_sha256:
amd64: "ffb5f8de10c62550dfddab66b36b57030721e0a44a3218e9e1181d7b59f121ca"
arm64: "5a4ec883379d51ee9ce1040d5e87f8d35e20387574dd8c947feb01eabc3c1b37"

# rustup-init only BOOTSTRAPS; the toolchain then tracks stable via `rustup
# update`, so this pin ages slowly and does not gate the Rust version.
# Upstream on both distros, not the distro package: Ubuntu's rustup is 1.26.0
# and ships no rustup-init at all, so it never creates ~/.cargo/bin -- the
# layout every later task in the rust role assumes.
rustup: "1.29.0"
rustup_sha256:
x86_64: "4acc9acc76d5079515b46346a485974457b5a79893cfb01112423c89aeb5aa10"
aarch64: "9732d6c5e2a098d3521fca8145d826ae0aaa067ef2385ead08e6feac88fa5792"

# fnm installs the n-1 Node major per user. Pinned by TAG, on the same
# reasoning as hyperi_versions above: a fetched release asset cannot be
# force-moved by a tag rewrite.
fnm: "v1.39.0"
14 changes: 2 additions & 12 deletions ansible/roles/contributor/tasks/git_scrub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,17 @@

- name: Install git-scrub (re-fetched GitHub release, Tier 3)
block:
# --pinned takes the CI-exact tag from group_vars, latest otherwise, so a
# pinned install never depends on the GitHub API.
#
# hyperi-ci carries no git-scrub pin, so --pinned falls through to latest.
# Adding an entry here without the matching hyperi-ci pin turns the build
# red via check_version_pins.py.
- name: Get latest git-scrub version from GitHub API
ansible.builtin.uri:
url: https://api.github.com/repos/hyperi-io/git-scrub/releases/latest
return_content: true
headers: "{{ hyperi_github_headers }}"
register: contributor_git_scrub_release
check_mode: false
when: not (hyperi_pinned | default(false) and 'git-scrub' in (hyperi_versions | default({})))

- name: Resolve the git-scrub tag (pinned or latest)
- name: Resolve the git-scrub tag
ansible.builtin.set_fact:
contributor_git_scrub_ref: >-
{{ hyperi_versions['git-scrub']
if (hyperi_pinned | default(false) and 'git-scrub' in (hyperi_versions | default({})))
else contributor_git_scrub_release.json.tag_name }}
contributor_git_scrub_ref: "{{ contributor_git_scrub_release.json.tag_name }}"

# hyperi_arch_deb already spells the architecture the way this release does.
- name: Build the git-scrub asset name
Expand Down
11 changes: 3 additions & 8 deletions ansible/roles/contributor/tasks/gitleaks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
# Fedora dnf (8.30.0 against upstream 8.30.1), Ubuntu release binary, macOS brew.
#
# Ubuntu universe carries 8.16.0 and freezes for the life of the release, which
# is fourteen minors adrift on a secret scanner. It also cannot honour the
# `hyperi_versions` pin, so a `--pinned` box ran a different scanner from CI.
# is fourteen minors adrift on a secret scanner.
#
# There is no better Linux channel to move to, and it was looked for. Upstream
# documents only Homebrew, Docker, Go and the release binaries -- they run no
Expand Down Expand Up @@ -67,14 +66,10 @@
headers: "{{ hyperi_github_headers }}"
register: contributor_gitleaks_latest
check_mode: false
when: not (hyperi_pinned | default(false) and 'gitleaks' in (hyperi_versions | default({})))

- name: Resolve the Gitleaks tag (pinned or latest)
- name: Resolve the Gitleaks tag
ansible.builtin.set_fact:
contributor_gitleaks_ref: >-
{{ hyperi_versions['gitleaks']
if (hyperi_pinned | default(false) and 'gitleaks' in (hyperi_versions | default({})))
else contributor_gitleaks_latest.json.tag_name }}
contributor_gitleaks_ref: "{{ contributor_gitleaks_latest.json.tag_name }}"

# gitleaks calls amd64 "x64"; arm64 keeps its own name.
- name: Map the architecture to the Gitleaks asset token
Expand Down
12 changes: 3 additions & 9 deletions ansible/roles/contributor/tasks/hadolint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,18 @@
ansible.builtin.set_fact:
contributor_hadolint_arch: "{{ 'arm64' if hyperi_arch_deb == 'arm64' else 'x86_64' }}"

# --pinned takes the CI-exact tag from group_vars; latest otherwise -- and
# only then do we hit the GitHub API, so a pinned install does not depend
# on it. Same shape as gitleaks.yml in this role.
# Same shape as gitleaks.yml in this role.
- name: Get latest hadolint version
ansible.builtin.uri:
url: https://api.github.com/repos/hadolint/hadolint/releases/latest
return_content: true
headers: "{{ hyperi_github_headers }}"
register: contributor_hadolint_latest
check_mode: false
when: not (hyperi_pinned | default(false) and 'hadolint' in (hyperi_versions | default({})))

- name: Resolve the hadolint tag (pinned or latest)
- name: Resolve the hadolint tag
ansible.builtin.set_fact:
contributor_hadolint_ref: >-
{{ hyperi_versions['hadolint']
if (hyperi_pinned | default(false) and 'hadolint' in (hyperi_versions | default({})))
else contributor_hadolint_latest.json.tag_name }}
contributor_hadolint_ref: "{{ contributor_hadolint_latest.json.tag_name }}"

- name: Download hadolint binary (Ubuntu)
ansible.builtin.get_url:
Expand Down
22 changes: 5 additions & 17 deletions ansible/roles/contributor/tasks/hyperi_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
# in place, not skipped when already present. `uv tool install --upgrade`
# installs it if missing and pulls the latest PyPI release if present, so a
# staff/contributor box that ran an earlier version does not stay pinned to it.
# (In --pinned mode this instead installs the version from versions.yml.)
- name: Install or upgrade hyperi-ci to the latest release
ansible.builtin.command:
cmd: uv tool install --upgrade hyperi-ci
Expand Down Expand Up @@ -104,14 +103,9 @@
# of THIS repo (see CONTRIBUTING), not something hyperi-ci calls.
#
# Not packaged anywhere, so cargo it is -- the bottom rung, and the only rung.
# --pinned takes the exact crates.io release from hyperi_versions -- latest otherwise.
- name: Install alint (repository-structure linter, NOT ansible-lint)
ansible.builtin.command:
cmd: >-
cargo install alint
{{ ('--version ' ~ (hyperi_versions['alint'] | regex_replace('^v', '')))
if (hyperi_pinned | default(false) and 'alint' in (hyperi_versions | default({})))
else '' }}
cmd: cargo install alint
creates: "{{ user_home }}/.cargo/bin/alint"
become: "{{ ansible_facts['distribution'] != 'MacOSX' }}"
become_user: "{{ actual_user if ansible_facts['distribution'] != 'MacOSX' else omit }}"
Expand Down Expand Up @@ -149,7 +143,7 @@
# honoured and the confined build can read only $HOME. Repos under /projects are
# invisible to it, and the resulting scan failure surfaces through hyperi-ci as
# "issues found (non-blocking)" -- a gate failing open while reading like a
# result. It also ignores hyperi_versions and refreshes on snapd's schedule.
# result. It also refreshes on snapd's own schedule.
- name: Install osv-scanner (macOS)
community.general.homebrew:
name: osv-scanner
Expand All @@ -168,24 +162,18 @@
- name: Install osv-scanner (Linux -- re-fetched GitHub release, Tier 3)
when: ansible_facts['distribution'] in ['Ubuntu', 'Fedora']
block:
# --pinned takes the CI-exact tag from group_vars; latest otherwise -- and
# only then do we hit the GitHub API, so a pinned install does not depend
# on it. Same shape as kubeconform in the infrastructure role.
# Same shape as kubeconform in the infrastructure role.
- name: Get latest osv-scanner version
ansible.builtin.uri:
url: https://api.github.com/repos/google/osv-scanner/releases/latest
return_content: true
headers: "{{ hyperi_github_headers }}"
register: contributor_osv_latest
check_mode: false
when: not (hyperi_pinned | default(false) and 'osv-scanner' in (hyperi_versions | default({})))

- name: Resolve the osv-scanner tag (pinned or latest)
- name: Resolve the osv-scanner tag
ansible.builtin.set_fact:
contributor_osv_ref: >-
{{ hyperi_versions['osv-scanner']
if (hyperi_pinned | default(false) and 'osv-scanner' in (hyperi_versions | default({})))
else contributor_osv_latest.json.tag_name }}
contributor_osv_ref: "{{ contributor_osv_latest.json.tag_name }}"

- name: Download osv-scanner
ansible.builtin.get_url:
Expand Down
9 changes: 3 additions & 6 deletions ansible/roles/developer-go/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
---
# Developer-Go defaults.
#
# The version lives in the SSoT -- hyperi_core_versions in
# inventories/localhost/group_vars/all.yml. This file only selects the checksum
# for the running architecture, so a Go bump stays a one-line edit there.

go_version: "{{ hyperi_core_versions.go }}"
go_sha256: "{{ hyperi_core_versions.go_sha256[hyperi_arch_deb | default('amd64')] }}"
# go_version and go_sha256 are not set here. Both are resolved from
# go.dev/dl/?mode=json when the role runs, so the install tracks the current
# stable release and still verifies what it downloads.

# Go is installed to /usr/local/go, so it is NOT on a non-login shell's PATH
# during the run itself -- /etc/profile.d is only sourced by login shells, and
Expand Down
Loading
Loading