bastion 0.55.3
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
# The checks of .gitea/workflows/ci.yml, for the copy of this repository on
|
||||
# GitHub. Gitea reads .gitea/workflows when it exists and then ignores this
|
||||
# directory, so each forge runs one of the two files, never both.
|
||||
#
|
||||
# The jobs, image and commands are the same as there. Every job runs in the Go
|
||||
# toolchain image deploy/build.sh builds releases with, pinned by the same
|
||||
# digest, so CI and the release use the same compiler. GitHub does not let a
|
||||
# job's container name come from env, so the digest is written out in each
|
||||
# job; it must match GO_IMAGE in deploy/build.sh and .gitea/workflows/ci.yml.
|
||||
# No action from the marketplace is used: the commit is fetched with git from
|
||||
# this repository's public URL, so nothing outside this file and the pinned
|
||||
# image runs. The job token can only read.
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# The pull request's own head, or the pushed commit.
|
||||
WANT: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
REPO_URL: ${{ github.server_url }}/${{ github.repository }}.git
|
||||
GOTOOLCHAIN: local
|
||||
CGO_ENABLED: "0"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh -eu {0}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
container:
|
||||
image: golang@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba
|
||||
env:
|
||||
PRIVATAE_REQUIRE_AGE: "1"
|
||||
steps:
|
||||
- name: tools
|
||||
# pdftotext, python3, setpriv and git are what the extract and
|
||||
# peer-identity tests call; without them those tests fail rather than
|
||||
# skip. Alpine's git has no http-backend (it is in git-daemon), which
|
||||
# the forge-token test serves its repository with.
|
||||
run: apk add -q --no-cache poppler-utils python3 setpriv curl git git-daemon
|
||||
- name: fetch the commit
|
||||
# The checkout belongs to the runner's user and the job runs as root,
|
||||
# so git is told the directory is safe; go build reads it to stamp the
|
||||
# binary with the commit.
|
||||
run: |
|
||||
set -o pipefail
|
||||
git config --global --add safe.directory "$PWD"
|
||||
git init -q .
|
||||
git fetch -q --depth=1 "$REPO_URL" "$WANT"
|
||||
git checkout -q --detach FETCH_HEAD
|
||||
test "$(git rev-parse HEAD)" = "$WANT"
|
||||
- name: age
|
||||
# The backup tests check this code against the age command itself: a
|
||||
# pinned age release, its archive checked against the SHA-256 below,
|
||||
# and PRIVATAE_REQUIRE_AGE makes those tests fail rather than skip if
|
||||
# it is missing.
|
||||
run: |
|
||||
case "$(uname -m)" in
|
||||
x86_64) a=amd64; sum=cbe24006683f8eb669266162894b9a522a1af52f2665fbc63a4bb032ed26ac10 ;;
|
||||
aarch64) a=arm64; sum=6b8dc4333c53a5a57c9e5834e3a48f92605d7154014cd07269ff3327db5d37f4 ;;
|
||||
*) echo "no pinned age release for $(uname -m)"; exit 1 ;;
|
||||
esac
|
||||
curl -fsSL -o /tmp/age.tgz "https://github.com/FiloSottile/age/releases/download/v1.3.2/age-v1.3.2-linux-$a.tar.gz"
|
||||
echo "$sum /tmp/age.tgz" | sha256sum -c -
|
||||
tar -xzf /tmp/age.tgz -C /tmp age/age
|
||||
/tmp/age/age --version
|
||||
echo "AGE_BIN=/tmp/age/age" >> "$GITHUB_ENV"
|
||||
- name: gofmt, go vet on linux/darwin/windows, build, go test
|
||||
working-directory: client-go
|
||||
run: |
|
||||
echo "== gofmt"; out="$(gofmt -l .)"; [ -z "$out" ] || { echo "$out"; exit 1; }
|
||||
for os in linux darwin windows; do echo "== go vet ($os)"; GOOS=$os go vet ./...; done
|
||||
echo "== go build"; go build -o /tmp/privatae-bastion .
|
||||
echo "== go test"; go test -count=1 ./...
|
||||
- name: the same for deploy/release-sign
|
||||
working-directory: deploy/release-sign
|
||||
run: |
|
||||
out="$(gofmt -l .)"; [ -z "$out" ] || { echo "$out"; exit 1; }
|
||||
for os in linux darwin windows; do GOOS=$os go vet ./...; done
|
||||
go test -count=1 ./...
|
||||
- name: staticcheck on linux, darwin and windows
|
||||
# The pinned staticcheck release, built with this toolchain from the
|
||||
# module proxy and checked against the checksum database.
|
||||
run: sh deploy/staticcheck.sh
|
||||
- name: the release workflow's GitHub step, against a fake API
|
||||
run: python3 -I deploy/test_github_release.py
|
||||
|
||||
personal-data:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
container:
|
||||
image: golang@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba
|
||||
steps:
|
||||
- name: tools
|
||||
run: apk add -q --no-cache bash git python3
|
||||
- name: fetch the commit
|
||||
run: |
|
||||
set -o pipefail
|
||||
git config --global --add safe.directory "$PWD"
|
||||
git init -q .
|
||||
git fetch -q --depth=1 "$REPO_URL" "$WANT"
|
||||
git checkout -q --detach FETCH_HEAD
|
||||
test "$(git rev-parse HEAD)" = "$WANT"
|
||||
- name: this file's image is the image releases are built with
|
||||
# Each job here names the digest itself, so a change to GO_IMAGE in
|
||||
# deploy/build.sh that missed this file fails here.
|
||||
run: |
|
||||
want="$(sed -n 's/^GO_IMAGE="\(golang@sha256:[0-9a-f]\{64\}\)"$/\1/p' deploy/build.sh)"
|
||||
test -n "$want"
|
||||
test "$(grep -c "^ image: $want\$" .github/workflows/ci.yml)" -eq 3
|
||||
test "$(grep -c '^ image: ' .github/workflows/ci.yml)" -eq 3
|
||||
grep -q "^ GO_IMAGE: $want\$" .gitea/workflows/ci.yml
|
||||
grep -q "^ GO_IMAGE: $want\$" .github/workflows/ci.yml
|
||||
- name: no person's data in the tree
|
||||
# Reads files, runs nothing from the tree. The term check needs the
|
||||
# maintainers' key and the entity-id check the reserved ids, which
|
||||
# this job never holds, so both are skipped and the run prints a NOTE
|
||||
# for each; the provenance, email and phone checks run.
|
||||
run: python3 -I scripts/test_no_personal_data.py
|
||||
- name: every test the claims table cites exists
|
||||
# docs/claims.md names, for each security claim, the test that fails
|
||||
# if the claim stops being true. A renamed or deleted test would leave
|
||||
# the claim looking covered; this fails the run instead. Reads files
|
||||
# and greps; runs nothing from the tree.
|
||||
run: bash deploy/check-claims.sh
|
||||
- name: no Host source file names in the tree
|
||||
# The member repository publishes this tree as a release was built,
|
||||
# and its release step refuses a path into the Host's Python
|
||||
# (server/... or brain/... .py): this repo has no such files, so the
|
||||
# path can only name another program's source. git grep exits 1 when
|
||||
# nothing matches and above 1 when it could not search; only 1 passes.
|
||||
run: |
|
||||
rc=0
|
||||
git grep -nIE 'server/[a-z_/]+\.py|brain/[a-z_/]+\.py' || rc=$?
|
||||
case "$rc" in
|
||||
1) ;;
|
||||
0) echo "these lines name another program's source file; describe it instead" >&2
|
||||
exit 1 ;;
|
||||
*) echo "git grep could not search the tree (exit $rc), so it was not checked" >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
fuzz:
|
||||
needs: test
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 20
|
||||
container:
|
||||
image: golang@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba
|
||||
steps:
|
||||
- name: tools
|
||||
run: apk add -q --no-cache bash git
|
||||
- name: fetch the commit
|
||||
run: |
|
||||
set -o pipefail
|
||||
git config --global --add safe.directory "$PWD"
|
||||
git init -q .
|
||||
git fetch -q --depth=1 "$REPO_URL" "$WANT"
|
||||
git checkout -q --detach FETCH_HEAD
|
||||
test "$(git rev-parse HEAD)" = "$WANT"
|
||||
- name: every fuzz target, 5 seconds each
|
||||
# A short pass on every commit. Run deploy/fuzz.sh with its default of
|
||||
# 20 seconds before changing a wall a host's input goes through.
|
||||
run: bash deploy/fuzz.sh 5
|
||||
|
||||
claims-on-a-machine:
|
||||
# The claim tests a container cannot run: the op and action-op sandboxes
|
||||
# (root, systemd units, overlayfs, a cgroup with the pids controller),
|
||||
# the egress tests in private user and network namespaces, and the root
|
||||
# command watch (nftables). They run here on the runner's own virtual
|
||||
# machine, as root, because that is what they test: the bastion as a
|
||||
# networked machine's system service. The machine is GitHub's and is
|
||||
# discarded after the job. The toolchain is the one in the pinned image.
|
||||
# Every test docs/claims.md cites is run, and the job fails if any of
|
||||
# them skips.
|
||||
needs: test
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
# This job runs on the runner itself, not in the image, and Ubuntu
|
||||
# 24.04's sh is dash 0.5.12-6ubuntu5, which has no pipefail (Debian added
|
||||
# it in 0.5.12-7): `set -o pipefail` there is a fatal error. bash has it.
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -eu {0}
|
||||
env:
|
||||
GO_IMAGE: golang@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba
|
||||
steps:
|
||||
- name: fetch the commit
|
||||
run: |
|
||||
set -o pipefail
|
||||
git init -q .
|
||||
git fetch -q --depth=1 "$REPO_URL" "$WANT"
|
||||
git checkout -q --detach FETCH_HEAD
|
||||
test "$(git rev-parse HEAD)" = "$WANT"
|
||||
- name: tools, and the pinned toolchain on the machine
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends nftables iproute2 poppler-utils >/dev/null
|
||||
# The forge-token claim test needs git 2.46 or later; Ubuntu 24.04's
|
||||
# own git is 2.43.
|
||||
if ! git version | awk '{split($3, v, "."); exit !(v[1] > 2 || (v[1] == 2 && v[2] >= 46))}'; then
|
||||
sudo add-apt-repository -y ppa:git-core/ppa >/dev/null
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git >/dev/null
|
||||
fi
|
||||
git version
|
||||
docker create --name go "$GO_IMAGE" >/dev/null
|
||||
sudo docker cp go:/usr/local/go /opt/go-pinned
|
||||
docker rm go >/dev/null
|
||||
/opt/go-pinned/bin/go version
|
||||
- name: age
|
||||
# The same pinned age release as the test job.
|
||||
run: |
|
||||
case "$(uname -m)" in
|
||||
x86_64) a=amd64; sum=cbe24006683f8eb669266162894b9a522a1af52f2665fbc63a4bb032ed26ac10 ;;
|
||||
aarch64) a=arm64; sum=6b8dc4333c53a5a57c9e5834e3a48f92605d7154014cd07269ff3327db5d37f4 ;;
|
||||
*) echo "no pinned age release for $(uname -m)"; exit 1 ;;
|
||||
esac
|
||||
curl -fsSL -o "$RUNNER_TEMP/age.tgz" "https://github.com/FiloSottile/age/releases/download/v1.3.2/age-v1.3.2-linux-$a.tar.gz"
|
||||
echo "$sum $RUNNER_TEMP/age.tgz" | sha256sum -c -
|
||||
tar -xzf "$RUNNER_TEMP/age.tgz" -C "$RUNNER_TEMP" age/age
|
||||
echo "AGE_BIN=$RUNNER_TEMP/age/age" >> "$GITHUB_ENV"
|
||||
- name: every cited test, as root
|
||||
working-directory: client-go
|
||||
run: |
|
||||
set -o pipefail
|
||||
tests="$(grep -o '_test\.go`: `[A-Za-z0-9_]*`' ../docs/claims.md | sed 's/.*`: `//; s/`$//' | sort -u | paste -sd'|' -)"
|
||||
test -n "$tests"
|
||||
sudo env PATH="/opt/go-pinned/bin:$PATH" HOME="$HOME" AGE_BIN="$AGE_BIN" PRIVATAE_REQUIRE_AGE=1 GOTOOLCHAIN=local CGO_ENABLED=0 \
|
||||
GOFLAGS=-mod=readonly GOMODCACHE="$HOME/go/pkg/mod" GOCACHE="$HOME/.cache/go-build" \
|
||||
go test -count=1 -json -run "^($tests)\$" . > "$RUNNER_TEMP/claims.json" || {
|
||||
grep -h '"Action":"fail"' "$RUNNER_TEMP/claims.json" | head -40; exit 1; }
|
||||
- name: none of them skipped
|
||||
run: bash deploy/check-claims.sh --skipped "$RUNNER_TEMP/claims.json"
|
||||
Reference in New Issue
Block a user