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
41 changes: 41 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: pr-gate

# Every pull request runs this repo's own check suite (scripts/check.sh) plus the shared em-dash and
# workflow-pinning guards. Those guards live in lib_bespok3d, mounted here as a git submodule, so the
# checkout must fetch it.
#
# The repo's own checkout uses the auto GITHUB_TOKEN, which is always valid for this repo. The submodule
# lives in a SEPARATE private repo that GITHUB_TOKEN cannot read, so it is fetched in its own step with a
# read token (MAIN_INDEX_TOKEN). The main checkout runs with persist-credentials off so it does not leave
# GITHUB_TOKEN in git config, where it would otherwise be reused for the submodule fetch and 403 on the
# private repo. The submodule URL in .gitmodules is HTTPS so the token applies.
#
# This is a check-only run: it never builds, packs, signs or publishes, so no signing key is in scope.
# The single secret it holds is the submodule read token. It is deliberately NOT named pr-build.yml: that
# name is reserved for a b3-builder preview build, which the pinning guard forbids from holding any secret
# at all. See the go-public finding: swap this token for a read-only one, or make lib_bespok3d public,
# before external forks open PRs (a fork PR receives no secret and its checkout of the private submodule
# would fail).
on:
pull_request:

jobs:
gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: false
persist-credentials: false

- name: Fetch the shared-tooling submodule
run: |
git config --global url."https://x-access-token:${{ secrets.MAIN_INDEX_TOKEN }}@github.com/".insteadOf "https://github.com/"
git submodule update --init --recursive

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Repo gate (shared detectors + check suite)
run: bash scripts/check.sh
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "lib_bespok3d"]
path = lib_bespok3d
url = https://github.com/Bespok3d/lib_bespok3d.git
1 change: 1 addition & 0 deletions lib_bespok3d
Submodule lib_bespok3d added at 8ce675
41 changes: 41 additions & 0 deletions scripts/check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# This repo's own gate: it must pass from this repo's root, with no sibling repo cloned except
# lib_bespok3d. Exits non-zero on any failure.
set -uo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# The shared gate helpers and the detectors that enforce a workspace-wide rule live in one place.
# See lib_bespok3d/tooling/README.md. This is the only line that knows where they are.
B3D_TOOLING="${B3D_TOOLING:-$REPO_ROOT/lib_bespok3d/tooling}"
# shellcheck source=/dev/null
. "$B3D_TOOLING/gate-lib.sh"

cd "$REPO_ROOT" || exit 1

echo ""
echo "reference-python-plugins gate"

b3d_python_tools

# print-time-human vendors humanize under files/site-packages, so its own tree is the import path
# its tests and its type checks resolve against.
export PYTHONPATH="$REPO_ROOT/print-time-human/files/site-packages"

# That vendored tree is gitignored (baked into the package at publish), so a clean checkout, which
# is what CI gets, has no humanize: the status-feed test would importorskip it and never run,
# leaving the gate green on an untested plugin. Provision the plugin's own declared dependency into
# the tree PYTHONPATH resolves against so the test actually exercises the code. B3D_PY is the gate's
# tool interpreter, provisioned by b3d_python_tools above.
"$B3D_PY" -m pip install --quiet --target "$REPO_ROOT/print-time-human/files/site-packages" -r "$REPO_ROOT/status-feed/requirements.txt"

run_check "pytest (status-feed)" pytest_in_dir "$REPO_ROOT/status-feed" tests
run_check "ruff (status-feed)" ruff_in_dir "$REPO_ROOT/status-feed" files tests
run_check "ruff (print-time-human)" ruff_in_dir "$REPO_ROOT/print-time-human" files/klipper

unset PYTHONPATH

workflow_pinning_check "$REPO_ROOT"
em_dash_check "$REPO_ROOT"
shellcheck_repo "$REPO_ROOT"

gate_summary || exit 1
Loading