Skip to content

Add GitHub Actions CI workflow with ruff and license-header checks#6

Merged
ViacheslavKlimov merged 7 commits intorelease/4.3from
ci-cd-release-4.3
Apr 29, 2026
Merged

Add GitHub Actions CI workflow with ruff and license-header checks#6
ViacheslavKlimov merged 7 commits intorelease/4.3from
ci-cd-release-4.3

Conversation

@ViacheslavKlimov
Copy link
Copy Markdown
Member

Summary

Adds a GitHub Actions CI pipeline to release/4.3 so PRs and pushes are validated before merge. Three parallel jobs:

  • test — pytest matrix on Python 3.10 and 3.13
  • lintruff check, ruff format --check, and a license-header gate (scripts/apply-license-headers.py --check)
  • build — full edition pipeline via scripts/build-packages.sh (regenerates all 3 editions, builds wheels, smoke-tests in clean venvs); uploads wheels-<sha> artifact

Workflow triggers on pull_request and on push to master or any release/* branch.

Alongside the workflow, this PR ships:

  • [tool.ruff] config in root pyproject.toml (E, W, F, I, B, UP rules; line-length 100; py310 target; per-file-ignores for tests/**; exclusions for generated tb_*_client/ packages).
  • scripts/apply-license-headers.py — idempotent automation that walks common/ and scripts/ and prepends the existing Apache 2.0 header (reused from post_process.py) to any .py file missing one. Supports --check for CI gating.
  • A one-time apply pass: ruff --fix + ruff format across all hand-written code, plus license headers added to common/__init__.py, common/_auth.py, common/_retry.py, scripts/post_process.py, scripts/flatten_docs.py, and scripts/apply-license-headers.py itself.
  • A stale-assertion fix in tests/test_post_process.py (controller count 57 → 58) — the assertion was already failing on release/4.3 independent of CI work.

Follow-up for maintainers

After merge, configure release/4.3 branch protection in repo settings to require these status checks: test (3.10), test (3.13), lint, build. A matching PR for master will follow.

- pyproject.toml gains [tool.ruff] config selecting E/W/F/I/B/UP rules
  with line-length 100, py310 target, per-file-ignores for tests, and
  exclusions for the generated tb_*_client/ packages.
- scripts/apply-license-headers.py is a new idempotent script that
  walks common/ and scripts/, prepending the existing LICENSE_HEADER
  template (reused from post_process.py) where missing. Supports
  --check for CI gating.
- Apply ruff --fix and ruff format across hand-written code; small
  manual fixes in scripts/post_process.py for unused vars and one
  unavoidable long string template (noqa).
- Run apply-license-headers.py once: headers added to common/
  overlay files (which ship inside the published wheels via
  generate-client.sh) and to scripts/*.py for parity with the
  shell scripts that already carry headers.
- Bump tests/test_post_process.py controller-count assertion 57 -> 58
  to match the CE spec at 4.4.0 (was stale on master).
Single workflow .github/workflows/ci.yml runs on pull_request and push
to master with three parallel jobs:

- test: pytest matrix on Python 3.10 and 3.13 (fail-fast off)
- lint: ruff check, ruff format --check, and the license-header
  --check gate
- build: full edition pipeline via scripts/build-packages.sh, with
  Java 17 and a cached openapi-generator JAR; uploads wheels-<sha>
  artifact

Top-level concurrency cancels superseded PR runs but lets master
pushes complete. Workflow has read-only contents permission.
Without an explicit [tool.poetry.dependencies].python entry, Poetry
defaults the project's supported Python range to '>=2.7,<2.8 || >=3.4',
which is incompatible with pytest-mock's '>=3.9' floor and breaks
'poetry install --no-root' on CI runners. Pin to '>=3.10,<4.0' to
match the per-edition pyproject.toml files.
The committed tb_ce_client package imports pydantic, urllib3,
python-dateutil, and typing-extensions at module load time, so
collecting the test files (which sys.path-import tb_ce_client) fails
in a fresh CI venv that only has pytest installed.

Install ce/ via 'poetry run pip install ./ce' so its [tool.poetry.
dependencies] block in ce/pyproject.toml drives the runtime dep
versions — single source of truth, no duplication into the root
pyproject.toml.
The exponential-backoff path computed base_ms = min(..., max_delay_ms)
and *then* applied +/-20% jitter, so a maxed-out base could exceed the
cap by up to 20% (e.g. 15000 -> 18000). The test
test_retry::TestDelayCappedAtMax::test_delay_capped_at_max asserts
delay <= max_delay_ms and was flaky for this reason — failing
deterministically about half the time on CI.

Re-apply min(delay_ms, max_delay_ms) after jitter. Sync the same
fix into the overlaid copies in tb_ce_client/, tb_pe_client/,
tb_paas_client/ so the published wheels carry the fix until the
next regeneration.
Running 'poetry install' from the root pyproject.toml — needed for
the test job in CI as well as local dev — generates poetry.lock as a
side effect. The repo's convention is not to track lock files (no
edition's poetry.lock is in git either; libraries should resolve
against the current pin ranges, not a frozen snapshot).
@ViacheslavKlimov ViacheslavKlimov merged commit 7ed99be into release/4.3 Apr 29, 2026
4 checks passed
@ViacheslavKlimov ViacheslavKlimov deleted the ci-cd-release-4.3 branch April 29, 2026 09:31
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.

1 participant