[OCaml] High Intensity Training Online
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.
.githooks/pre-push
@@ -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
@@ -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
@@ -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
@@ -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)"