Skip to content

Commit 016817d

Browse files
feat: add Tailwind CSS pipeline, tag-aware cloning & overhaul CI/CD (#352)
Frontend * introduce Tailwind CSS (package.json, tailwind.config.js, input CSS) * build site.css on-the-fly (removed tracked artefact; added .gitignore) * new favicon/icon assets & template cleanup * split JS into modular files Docker * replace single-stage image with 3-stage build • css-builder (Node 20 alpine) → compiles Tailwind • python-builder installs project with PEP 621 metadata • runtime image copies site-packages + compiled CSS, runs as uid 1000 CI/CD * ci.yml: cache by pyproject.toml, install with `pip -e .[dev]` * new frontend job builds/archives CSS after tests * publish.yml: build CSS first, then wheel/sdist; trusted OIDC upload * tidy scorecard workflow Core library * clone.py, parser & utils now resolve tags in addition to branches/commits * fallback branch/tag discovery when `git ls-remote` fails * compat\_func.py back-ports Path.readlink / str.removesuffix for Py 3.8 Tooling & docs * add `[dev]` extra, drop requirements-dev.txt & its pre-commit fixer * refreshed CONTRIBUTING.md with Node/Tailwind instructions * updated tests for new tag logic
1 parent 2b1f228 commit 016817d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2633
-460
lines changed

.github/dependabot.yml

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
version: 2
22
updates:
3+
# ─── Python (pip) ─────────────────────────────
34
- package-ecosystem: "pip"
45
directory: "/"
5-
schedule:
6-
interval: "daily"
7-
time: "06:00"
8-
timezone: "UTC"
9-
open-pull-requests-limit: 5
10-
labels:
11-
- "dependencies"
12-
- "pip"
6+
schedule: { interval: "weekly" }
7+
labels: [ "dependencies", "pip" ]
8+
groups: # Group patches & minors from dev-only tools
9+
dev-py:
10+
dependency-type: "development"
11+
update-types: ["minor", "patch"]
12+
13+
# ─── Node (npm) ───────────────────────────────
14+
- package-ecosystem: "npm"
15+
directory: "/"
16+
schedule: { interval: "weekly" }
17+
labels: [ "dependencies", "npm" ]
18+
cooldown: # wait before opening PRs
19+
semver-major-days: 30
20+
semver-minor-days: 7
21+
semver-patch-days: 3
22+
23+
# ─── GitHub Actions ───────────────────────────
24+
- package-ecosystem: "github-actions"
25+
directory: "/"
26+
schedule: { interval: "weekly" }
27+
labels: [ "dependencies", "gh-actions" ]

.github/workflows/ci.yml

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,50 @@ jobs:
2525
uses: actions/setup-python@v5
2626
with:
2727
python-version: ${{ matrix.python-version }}
28+
- name: Locate pip cache
29+
id: pip-cache
30+
shell: bash
31+
run: echo "dir=$(python -m pip cache dir)" >> "$GITHUB_OUTPUT"
2832

2933
- name: Cache pip
3034
uses: actions/cache@v4
3135
with:
32-
path: ~/.cache/pip
33-
key: ${{ runner.os }}-pip-${{ hashFiles('**/*requirements*.txt') }}
34-
restore-keys: |
35-
${{ runner.os }}-pip-
36-
36+
path: ${{ steps.pip-cache.outputs.dir }}
37+
key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
38+
restore-keys: ${{ runner.os }}-pip-
3739
- name: Install dependencies
3840
run: |
39-
pip install --upgrade pip
40-
pip install -r requirements-dev.txt
41+
python -m pip install --upgrade pip
42+
python -m pip install ".[dev]"
4143
4244
- name: Run tests
43-
run: |
44-
pytest
45+
run: pytest
4546

4647
# Run pre-commit only on Python 3.13 + ubuntu.
4748
- name: Run pre-commit hooks
49+
uses: pre-commit/action@v3.0.1
4850
if: ${{ matrix.python-version == '3.13' && matrix.os == 'ubuntu-latest' }}
49-
run: |
50-
pre-commit run --all-files
51+
52+
frontend:
53+
needs: test # Builds Tailwind CSS only if tests pass
54+
runs-on: ubuntu-latest
55+
steps:
56+
- uses: actions/checkout@v4
57+
58+
- name: Set up Node
59+
uses: actions/setup-node@v4
60+
with:
61+
node-version: 20
62+
cache: npm
63+
64+
- name: Install Node deps
65+
run: npm ci
66+
67+
- name: Build CSS
68+
run: npm run build:css # Creates src/static/css/site.css
69+
70+
- name: Upload artefact
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: static-css
74+
path: src/static/css/site.css

.github/workflows/publish.yml

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,88 @@
1-
name: "Publish to PyPI"
1+
name: Publish to PyPI
22

33
on:
44
release:
5-
types: [created]
6-
workflow_dispatch:
5+
types: [created] # Run when you click “Publish release”
6+
workflow_dispatch: # ... or run it manually from the Actions tab
77

88
permissions:
99
contents: read
1010

11+
# ── Build the Tailwind CSS bundle ───────────────────────────────
1112
jobs:
13+
frontend-build:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Setup Node
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: 20
23+
cache: npm
24+
cache-dependency-path: package-lock.json
25+
26+
- name: Install deps + build Tailwind
27+
run: |
28+
npm ci
29+
npm run build:css
30+
31+
- name: Upload built CSS
32+
uses: actions/upload-artifact@v4
33+
with:
34+
name: frontend-assets
35+
path: src/static/css/site.css
36+
if-no-files-found: error
37+
38+
# ── Build wheel/sdist (needs CSS) and upload “dist/” ────────────
1239
release-build:
40+
needs: frontend-build
1341
runs-on: ubuntu-latest
42+
1443
steps:
1544
- uses: actions/checkout@v4
16-
- uses: actions/setup-python@v5
45+
46+
# Grab site.css produced above
47+
- uses: actions/download-artifact@v4
48+
with:
49+
name: frontend-assets
50+
path: src/static/css/
51+
52+
- name: Set up Python 3.13
53+
uses: actions/setup-python@v5
1754
with:
1855
python-version: "3.13"
19-
- name: Build package
56+
cache: pip
57+
cache-dependency-path: pyproject.toml
58+
59+
- name: Install build backend
2060
run: |
21-
pip install build
61+
python -m pip install --upgrade pip
62+
python -m pip install build twine
2263
python -m build
23-
- uses: actions/upload-artifact@v4
64+
twine check dist/*
65+
- name: Upload dist artefact
66+
uses: actions/upload-artifact@v4
2467
with:
2568
name: dist
2669
path: dist/
2770

71+
# ── Publish to PyPI (only if “dist/” succeeded) ─────────────────
2872
pypi-publish:
29-
needs: [release-build]
73+
needs: release-build
3074
runs-on: ubuntu-latest
31-
environment: pypi
75+
environment: pypi # Creates the “pypi” environment in repo-settings
76+
3277
permissions:
33-
id-token: write
78+
id-token: write # OIDC token for trusted publishing
79+
3480
steps:
3581
- uses: actions/download-artifact@v4
3682
with:
3783
name: dist
3884
path: dist/
85+
3986
- uses: pypa/gh-action-pypi-publish@release/v1
87+
with:
88+
verbose: true

.github/workflows/scorecard.yml

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,39 @@
11
name: OSSF Scorecard
22
on:
3-
# For Branch-Protection check. Only the default branch is supported. See
4-
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
53
branch_protection_rule:
6-
# To guarantee Maintained check is occasionally updated. See
7-
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
84
schedule:
9-
- cron: '33 11 * * 2'
5+
- cron: '33 11 * * 2' # Every Tuesday at 11:33 AM UTC
106
push:
11-
branches: [ "main" ]
7+
branches: [ main ]
128

13-
# Declare default permissions as read only.
14-
permissions: read-all
9+
permissions: read-all # Default for the whole workflow
10+
11+
concurrency: # (optional) avoid overlapping runs
12+
group: scorecard-${{ github.ref }}
13+
cancel-in-progress: true
1514

1615
jobs:
1716
analysis:
1817
name: Scorecard analysis
1918
runs-on: ubuntu-latest
2019
permissions:
21-
# Needed to upload the results to code-scanning dashboard.
22-
security-events: write
23-
# Needed to publish results and get a badge (see publish_results below).
24-
id-token: write
20+
security-events: write # upload SARIF to code-scanning
21+
id-token: write # publish results for the badge
2522

2623
steps:
27-
- name: "Checkout code"
28-
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
24+
- name: Checkout
25+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
2926
with:
3027
persist-credentials: false
3128

32-
- name: "Run analysis"
33-
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
29+
- name: Run Scorecard
30+
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736
3431
with:
3532
results_file: results.sarif
3633
results_format: sarif
34+
publish_results: true # enables the public badge
3735

38-
# Public repositories:
39-
# - Publish results to OpenSSF REST API for easy access by consumers
40-
# - Allows the repository to include the Scorecard badge.
41-
# - See https://github.com/ossf/scorecard-action#publishing-results.
42-
publish_results: true
43-
44-
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
45-
# format to the repository Actions tab.
46-
47-
# Upload the results to GitHub's code scanning dashboard (optional).
48-
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
49-
- name: "Upload to code-scanning"
36+
- name: Upload to code-scanning
5037
uses: github/codeql-action/upload-sarif@v3
5138
with:
5239
sarif_file: results.sarif

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ cython_debug/
170170
# JavaScript tooling
171171
node_modules/
172172

173+
# CSS
174+
src/static/css/site.css
175+
173176
# Project specific
174177
history.txt
175178
cleanup.py

0 commit comments

Comments
 (0)