Skip to content

tests: the moe_mixed import guard must locate the module, not the repo #27

tests: the moe_mixed import guard must locate the module, not the repo

tests: the moe_mixed import guard must locate the module, not the repo #27

Workflow file for this run

# gridbook release: build, verify, publish to PyPI, attach to a GitHub Release.
#
# TRIGGER: tag pushes matching `v*` ONLY. There is deliberately no `push:
# branches:` and no `release:` trigger, so this file is safe to merge before the
# PyPI project exists -- merging it, or any later commit to master, can never
# attempt an upload. The first publish happens only when a human pushes a tag.
#
# ROUTING: a PEP 440 pre-release version (v0.1.0rc1, v0.1.0a1, ...) goes to
# TestPyPI; a final version goes to PyPI. Rehearse on TestPyPI first -- a PyPI
# version number can never be reused, even after deleting the release.
#
# AUTH: Trusted Publishing (OIDC). No API token, no repository secret. The
# one-time PyPI-side setup is written out in docs/RELEASING.md; until it is
# done, the publish job fails with an OIDC error and nothing is uploaded.
#
# Action pins: exact patch tags, latest releases checked 2026-07-28. See the
# header of ci.yml for the pinning rationale.
name: Release
on:
push:
tags: ["v*"]
permissions:
contents: read
jobs:
build:
name: build + verify tag
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.meta.outputs.version }}
prerelease: ${{ steps.meta.outputs.prerelease }}
environment: ${{ steps.meta.outputs.environment }}
repository_url: ${{ steps.meta.outputs.repository_url }}
project_url: ${{ steps.meta.outputs.project_url }}
wheel_sha256: ${{ steps.meta.outputs.wheel_sha256 }}
steps:
- uses: actions/checkout@v7.0.1
with:
# The release tag must be proven reachable from the public release
# branch. A one-commit checkout cannot establish that ancestry.
fetch-depth: 0
- name: Tag commit must be reachable from master
run: |
set -euo pipefail
git fetch --no-tags origin \
+refs/heads/master:refs/remotes/origin/master
tag_commit="$(git rev-parse "${GITHUB_REF}^{commit}")"
master_commit="$(git rev-parse refs/remotes/origin/master)"
if ! git merge-base --is-ancestor "${tag_commit}" "${master_commit}"; then
echo "::error::${GITHUB_REF_NAME} targets ${tag_commit}, which is not reachable from origin/master ${master_commit}"
exit 1
fi
echo "${GITHUB_REF_NAME}: ${tag_commit} is reachable from origin/master ${master_commit}"
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.12"
- name: Install build tooling
run: python -m pip install --upgrade pip build twine packaging
- name: Build
run: python -m build
- name: twine check
run: python -m twine check --strict dist/*
- name: Assert native sources are packaged
run: python .github/scripts/check_dist.py dist .
# The tag is the release's identity; if it disagrees with the version
# actually baked into the artifact, the wrong thing is about to be
# published under the wrong name. Fail before any upload.
- name: Tag must match the built version
id: meta
run: |
python - "$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT" <<'PY'
import glob, hashlib, os, sys
from packaging.utils import parse_wheel_filename
from packaging.version import Version
tag = sys.argv[1]
if not tag.startswith("v"):
sys.exit(f"tag {tag!r} must be of the form vX.Y.Z")
wheels = glob.glob("dist/*.whl")
if len(wheels) != 1:
sys.exit(f"expected exactly one wheel, got {wheels}")
_, built, _, _ = parse_wheel_filename(os.path.basename(wheels[0]))
want = Version(tag[1:])
if want != built:
sys.exit(f"tag {tag} means version {want}, but the build produced "
f"{built}. Bump the version in the source, commit, then "
f"re-tag.")
pre = built.is_prerelease
print(f"version={built}")
print(f"prerelease={str(pre).lower()}")
print(f"environment={'testpypi' if pre else 'pypi'}")
print("repository_url=" + ("https://test.pypi.org/legacy/" if pre
else "https://upload.pypi.org/legacy/"))
print("project_url=" + ("https://test.pypi.org/p/gridbook" if pre
else "https://pypi.org/p/gridbook"))
with open(wheels[0], "rb") as handle:
wheel_sha256 = hashlib.file_digest(handle, "sha256").hexdigest()
print(f"wheel_sha256={wheel_sha256}")
print(f"wheel sha256: {wheel_sha256}", file=sys.stderr)
print(f"{built} -> {'TestPyPI' if pre else 'PyPI'}", file=sys.stderr)
PY
- uses: actions/upload-artifact@v7.0.1
with:
name: dist
path: dist/
if-no-files-found: error
# Same gate as CI, re-run against the exact artifact about to be published:
# the wheel is installed non-editable into a clean interpreter and the
# packaged CUDA sources must resolve from site-packages. This is the check
# that a broken package cannot pass.
verify:
name: verify installed wheel
needs: build
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7.0.1
- uses: actions/setup-python@v7.0.0
with:
python-version: "3.12"
- uses: actions/download-artifact@v8.0.1
with:
name: dist
path: dist
- name: Downloaded wheel must match the build receipt
env:
EXPECTED_WHEEL_SHA256: ${{ needs.build.outputs.wheel_sha256 }}
run: |
python - "$EXPECTED_WHEEL_SHA256" <<'PY'
import glob, hashlib, sys
wheels = glob.glob("dist/*.whl")
if len(wheels) != 1:
sys.exit(f"expected exactly one wheel, got {wheels}")
with open(wheels[0], "rb") as handle:
actual = hashlib.file_digest(handle, "sha256").hexdigest()
if actual != sys.argv[1]:
sys.exit(f"wheel digest changed after build: {actual} != {sys.argv[1]}")
print(f"verified wheel sha256: {actual}")
PY
- name: Install CPU torch
run: |
python -m pip install --upgrade pip
python -m pip install torch \
--index-url https://download.pytorch.org/whl/cpu
- name: Install the wheel with its dependencies
run: python -m pip install pytest dist/*.whl
- name: Stage tests outside the checkout
run: cp -r tests "${RUNNER_TEMP}/gbtests"
- name: Post-install checks
working-directory: ${{ runner.temp }}
run: python "${GITHUB_WORKSPACE}/.github/scripts/check_installed.py"
- name: Run GPU-free tests
working-directory: ${{ runner.temp }}
run: |
bash "${GITHUB_WORKSPACE}/.github/scripts/run_cpu_tests.sh" \
"${RUNNER_TEMP}/gbtests"
publish:
name: publish to ${{ needs.build.outputs.environment }}
needs: [build, verify]
runs-on: ubuntu-24.04
# A fork that pushes a v* tag must never attempt to publish gridbook.
if: github.repository == 'RobTand/gridbook'
environment:
# `pypi` / `testpypi` GitHub environments. Add a required reviewer to the
# `pypi` environment to get a human approval gate in front of the one
# irreversible step in this workflow (docs/RELEASING.md).
name: ${{ needs.build.outputs.environment }}
url: ${{ needs.build.outputs.project_url }}
permissions:
id-token: write # OIDC token for Trusted Publishing. Nothing else.
steps:
- uses: actions/download-artifact@v8.0.1
with:
name: dist
path: dist
- name: Downloaded wheel must match the verified build
env:
EXPECTED_WHEEL_SHA256: ${{ needs.build.outputs.wheel_sha256 }}
run: |
python - "$EXPECTED_WHEEL_SHA256" <<'PY'
import glob, hashlib, sys
wheels = glob.glob("dist/*.whl")
if len(wheels) != 1:
sys.exit(f"expected exactly one wheel, got {wheels}")
with open(wheels[0], "rb") as handle:
actual = hashlib.file_digest(handle, "sha256").hexdigest()
if actual != sys.argv[1]:
sys.exit(f"wheel digest changed before publish: {actual} != {sys.argv[1]}")
print(f"verified wheel sha256: {actual}")
PY
# Pinned to an exact release rather than the `release/v1` branch that
# PyPA's own docs suggest: a branch ref is re-pointable, and this action
# holds an OIDC token that can upload under our project name.
# Publishes every file in dist/ and, by default, PEP 740 attestations.
# `skip-existing` is deliberately NOT set: re-publishing an existing
# version is a mistake, and PyPI must refuse it loudly.
- uses: pypa/gh-action-pypi-publish@v1.14.2
with:
repository-url: ${{ needs.build.outputs.repository_url }}
print-hash: true
github-release:
name: github release
needs: [build, publish]
runs-on: ubuntu-24.04
permissions:
contents: write # only this job may write to the repo
steps:
- uses: actions/download-artifact@v8.0.1
with:
name: dist
path: dist
- name: Release wheel must match the published build
env:
EXPECTED_WHEEL_SHA256: ${{ needs.build.outputs.wheel_sha256 }}
run: |
python - "$EXPECTED_WHEEL_SHA256" <<'PY'
import glob, hashlib, sys
wheels = glob.glob("dist/*.whl")
if len(wheels) != 1:
sys.exit(f"expected exactly one wheel, got {wheels}")
with open(wheels[0], "rb") as handle:
actual = hashlib.file_digest(handle, "sha256").hexdigest()
if actual != sys.argv[1]:
sys.exit(f"wheel digest changed before GitHub Release: {actual} != {sys.argv[1]}")
print(f"verified wheel sha256: {actual}")
PY
# gh is preinstalled on GitHub-hosted runners, so the release step needs
# no third-party action and no extra pin. GH_REPO is required because this
# job deliberately does not check out the repo, so gh has no git remote to
# infer the target from.
- name: Create the GitHub Release
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
PRERELEASE: ${{ needs.build.outputs.prerelease }}
VERSION: ${{ needs.build.outputs.version }}
run: |
set -euo pipefail
args=(--generate-notes --title "gridbook ${VERSION}")
if [ "${PRERELEASE}" = "true" ]; then
args+=(--prerelease)
fi
gh release create "${GITHUB_REF_NAME}" "${args[@]}" dist/*