ci gate pushes with a versioned pre-push hook, not a GitHub workflow

The remote is a self-hosted bare repository, so the GitHub Actions workflow added earlier could never run. Remove it. Enforce the gates where they can actually fire: a pre-push hook, committed under .githooks, runs scripts/ci.sh before any push leaves the machine, so the deployment host's receive hook only ever sees a ref that type-checks, passes every test, and is formatted. Enable it once per clone with scripts/install-hooks.sh, which points core.hooksPath at the versioned directory. To bypass deliberately, pass --no-verify.

Commit
8a6b3378c015480ea8995497dffe7f6c0804183b
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
.githooks/pre-push
index 00000000..a3ad1f51 000000..100755
@@ -0,0 +1,19 @@
1 Added: #!/usr/bin/env sh
2 Added: # Run the definition-of-done gates before any push leaves this machine, so the
3 Added: # deployment host's post-receive hook only ever sees a ref that type-checks,
4 Added: # passes every test, and is formatted.
5 Added: #
6 Added: # Enable once per clone: scripts/install-hooks.sh
7 Added: # Bypass deliberately: git push --no-verify
8 Added:
9 Added: set -eu
10 Added:
11 Added: cd "$(git rev-parse --show-toplevel)"
12 Added:
13 Added: # Prefer the project's opam switch when direnv provides it, so the hook uses the
14 Added: # same toolchain as a developer shell.
15 Added: if command -v direnv >/dev/null 2>&1; then
16 Added: exec direnv exec . sh scripts/ci.sh
17 Added: else
18 Added: exec sh scripts/ci.sh
19 Added: fi
.github/workflows/ci.yml
index 87e45f05..00000000 100644..000000
@@ -1,35 +0,0 @@
1 Removed: # Runs the definition-of-done gates on every push and pull request. The gates
2 Removed: # themselves live in scripts/ci.sh, so this workflow and any other runner (a
3 Removed: # git hook on the deployment host, a cron job) enforce the identical bar.
4 Removed: #
5 Removed: # The primary remote is a self-hosted bare repository, so this file is inert
6 Removed: # there. It runs wherever the repository is mirrored to GitHub.
7 Removed:
8 Removed: name: ci
9 Removed:
10 Removed: on:
11 Removed: push:
12 Removed: pull_request:
13 Removed:
14 Removed: jobs:
15 Removed: gates:
16 Removed: runs-on: ubuntu-latest
17 Removed: steps:
18 Removed: - uses: actions/checkout@v4
19 Removed:
20 Removed: - name: Set up OCaml
21 Removed: uses: ocaml/setup-ocaml@v3
22 Removed: with:
23 Removed: ocaml-compiler: "5.1"
24 Removed: dune-cache: true
25 Removed:
26 Removed: - name: Install dependencies
27 Removed: # --with-test brings alcotest; ocamlformat is pinned in the opam file
28 Removed: # under with-dev-setup, so install it explicitly at the pinned version
29 Removed: # the .ocamlformat file names.
30 Removed: run: |
31 Removed: opam install . --deps-only --with-test --yes
32 Removed: opam install ocamlformat.0.29.0 --yes
33 Removed:
34 Removed: - name: Run the gates
35 Removed: run: opam exec -- sh scripts/ci.sh
scripts/ci.sh
index 282e12a3..a25b71ce 100755..100755
@@ -5,9 +5,10 @@
5 5 # 2. dune runtest runs every Alcotest suite
6 6 # 3. dune build @fmt confirms ocamlformat and dune formatting are applied
7 7 #
8 Removed: # Exit status is non-zero if any gate fails, so a git hook, a cron job, or a
9 Removed: # hosted CI runner can all enforce the same bar with one call. The build
10 Removed: # directory is isolated so a developer's watch build is never disturbed.
8 Added: # Exit status is non-zero if any gate fails, so the pre-push hook in .githooks,
9 Added: # a cron job, or the deployment host's receive hook can all enforce the same bar
10 Added: # with one call. The build directory is isolated so a developer's watch build
11 Added: # is never disturbed.
11 12 #
12 13 # Usage: scripts/ci.sh run all gates
13 14 # BUILD_DIR=... scripts/ci.sh override the build directory
scripts/install-hooks.sh
index 00000000..2e6d82a0 000000..100755
@@ -0,0 +1,10 @@
1 Added: #!/usr/bin/env sh
2 Added: # Point git at the versioned hooks in .githooks, so the pre-push gate is part of
3 Added: # the repository rather than a per-clone manual step. Run once per clone.
4 Added:
5 Added: set -eu
6 Added:
7 Added: cd "$(git rev-parse --show-toplevel)"
8 Added: git config core.hooksPath .githooks
9 Added: chmod +x .githooks/*
10 Added: printf 'git hooks enabled: %s\n' "$(git config --get core.hooksPath)"