Skip to content

ci: move to uv, shared tests and tag-only publish - #132

Open
singlerider wants to merge 10 commits into
blacklanternsecurity:devfrom
singlerider:ci/publish-on-tag
Open

singlerider wants to merge 10 commits into
blacklanternsecurity:devfrom
singlerider:ci/publish-on-tag

Conversation

@singlerider

@singlerider singlerider commented Oct 3, 2026 •

Copy link
Copy Markdown

What changed

  • tests.yml no longer publishes or tags. It used to upload to PyPI on every master push with PYPI_API_TOKEN, then guess a release from git describe and push a bot tag.
  • Moved from poetry to uv (toolchain.md). PEP 621 [project] keeps the same dependency bounds, hatchling builds the wheel (static and template assets verified in it), and uv.lock replaces poetry.lock. poetry-dynamic-versioning (version = commit distance) is removed. The version is declared as 0.1.103, the last PyPI release.
  • tests.yml calls the shared python-tests.yml in blacklanternsecurity/CLA at one pinned SHA. The matrix comes from requires-python. The tesseract install and the AppArmor userns sysctl Chrome needs live in scripts/ci-setup.sh.
  • publish.yml runs on v* tags only: shared release-check.yml, then tests, then PyPI OIDC upload in pypi (top-level job), then shared publish.yml (release plus SPDX JSON SBOM).
  • ruff pinned ==0.11.10. The CLA caller is new and uses the shared SHA. Builds on ci: pin the runner image to ubuntu-24.04 #130.

Required check: python / passed. Removed job: publish. Dependabot must use the uv ecosystem (#133).

Validation

$ uv run ruff check -q && uv run ruff format --check -q
ruff check + format --check: clean (ruff 0.11.10)
$ uv build && unzip -l dist/*.whl | grep -E 'static|templates'
webcap/server/static/react-dom.production.min.js
webcap/server/static/react.production.min.js
webcap/server/static/webcap.png
webcap/server/templates/index.html
$ uv version --short
0.1.103
$ uvx --from actionlint-py actionlint
(no findings)

Screenshot tests need Chrome, which this machine does not have. CI runs them.

Admin steps

  • Register a PyPI trusted publisher for this repo, workflow publish.yml, environment pypi, then delete PYPI_API_TOKEN.

Related issues

  • Part of blacklanternsecurity/bbot-enterprise#139
  • Part of blacklanternsecurity/bbot-enterprise#140
  • Part of blacklanternsecurity/bbot-enterprise#149
  • Part of blacklanternsecurity/bbot-enterprise#155
  • Part of blacklanternsecurity/bbot-enterprise#156

ubuntu-latest is a label GitHub moves. The image changes under us and
a green pipeline turns red on a morning nobody touched the code.
Pinning to ubuntu-24.04 means the runner moves when we move it.

Action refs are untouched; the version-tagged ones stay as they are
and Dependabot keeps watching them.
The lint job installed ruff with no version, so it picked up 0.16.9,
which flags 70 errors in existing code. Lint failed and the test
matrix never ran on the new ubuntu-24.04 runner.

Pin ruff with == in the workflow and in the dev dependency group, at
the 0.11.10 already locked in poetry.lock. That version passes ruff
check and ruff format clean on this branch. Bump it deliberately in a
commit that also fixes what the new version flags.
On ubuntu-24.04 chromium-browser is a snap transitional package whose
install fails in the runner, which broke every test job once the
runner was pinned. The image already ships google-chrome, which
webcap's binary detection finds.
AppArmor restricts unprivileged user namespaces on 24.04, so Chrome
aborted with 'No usable sandbox'. Lift the restriction on the runner
rather than running Chrome with --no-sandbox.
`ruff format` without --check rewrote files in the runner and always
passed, so formatting was never enforced. The ruff pin was also
repeated in the workflow; install the locked dev group instead.
tests.yml built and published to PyPI on every push to master with a
long-lived token, then guessed whether to tag by comparing major.minor
against git describe and pushed a tag as github-actions[bot]. The
version itself came from poetry-dynamic-versioning as commit distance,
so the published artifact matched nothing in the tree.

The version is now declared in pyproject.toml, set to 0.1.103, the
last version on PyPI. publish.yml runs only on v* tags, refuses tags
outside vMAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH-rc.N or not equal to
the declared version, reruns tests, uploads via trusted publishing in
the pypi environment, and creates the GitHub Release with an SPDX JSON
SBOM in the same run. CI never tags.

tests.yml gains a contents: read permissions block and workflow_call,
actions are pinned to commit SHAs, and CLA calls the shared reusable
workflow.
@codecov-commenter

codecov-commenter commented Oct 3, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (dev@39628b9). Learn more about missing BASE report.

Additional details and impacted files
@@          Coverage Diff           @@
##             dev     #132   +/-   ##
======================================
  Coverage       ?   76.98%           
======================================
  Files          ?       13           
  Lines          ?      934           
  Branches       ?        0           
======================================
  Hits           ?      719           
  Misses         ?      215           
  Partials       ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

toolchain.md makes uv the package manager. Poetry kept a second lock
format, a second install path in CI, and pipx run poetry calls in the
publish path. Dependencies move to PEP 621 [project] tables with the
same bounds poetry's caret ranges expressed, the dev group moves to
[dependency-groups], and hatchling builds the wheel (static and
template assets still ship: verified with unzip -l on the built wheel).

The license string becomes the valid SPDX id GPL-3.0.
The previous commit removed poetry. Lint, tests, and publish now use
setup-uv and the uv.lock, so CI installs exactly what is locked.
tests.yml, publish.yml, and the CLA caller now use the org workflows in
blacklanternsecurity/CLA at one pinned SHA instead of carrying copies.

- tests: python-tests.yml runs ruff then pytest on every CPython that
  requires-python allows, replacing the literal 3.9 to 3.13 matrix.
  The tesseract install and the AppArmor userns sysctl Chrome needs
  move to scripts/ci-setup.sh, passed as setup-script.
- publish: release-check.yml validates the tag shape and that it equals
  [project].version. pypi stays a top-level job because PyPI trusted
  publishing does not work inside a reusable workflow. publish.yml then
  creates the release with the SPDX SBOM.
- archive/** is no longer excluded: archive tags are not created.
Picks up secret-env skipping absent secrets on fork PRs and rust-tests
running setup-script before clippy. No caller input changes.
@singlerider singlerider changed the title ci: publish on version tags only, declare the version ci: move to uv, shared tests and tag-only publish Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants