Skip to content
Open
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
4 changes: 4 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[flake8]
select = CAR,TXB
extend_exclude = migrations,.venv
require_plugins = flake8-carrot
151 changes: 90 additions & 61 deletions .github/workflows/check-build-deploy.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: Check, Build and Deploy

on:
"on":
pull_request:
branches: [main]
push:
branches: [main]
tags: ["v*"]
tags: [v*]

jobs:
uv-check:
Expand All @@ -22,13 +22,37 @@ jobs:
- name: Check uv.lock (ensure all dependencies up to date)
run: uv lock --check

mypy:
needs: [uv-check]
runs-on: ubuntu-latest
# yamllint disable-line rule:key-ordering
flake8:
env:
UV_FROZEN: true
UV_NO_SYNC: true
UV_PYTHON_DOWNLOADS: never
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5

- name: Set Up Python
uses: actions/setup-python@v6
with:
python-version: 3.14

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

- name: Run Flake8
run: uvx --python 3.14 --with flake8-carrot -- flake8

mypy: # yamllint disable-line rule:key-ordering
env:
UV_FROZEN: true
UV_NO_SYNC: true
UV_PYTHON_DOWNLOADS: never
needs: [uv-check]
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5
Expand All @@ -46,29 +70,36 @@ jobs:
- name: Install mypy From Locked Dependencies
run: uv sync --no-group dev --group type-check

- name: Store Hashed Python Version
id: store-hashed-python-version
- id: store-hashed-python-version
name: Store Hashed Python Version
run: echo "hashed_python_version=$(uv run -- python -VV | sha256sum | cut -d' ' -f1)"
>> $GITHUB_OUTPUT

- uses: actions/cache@v4
with:
path: ./.mypy_cache
key: mypy|${{steps.store-hashed-python-version.outputs.hashed_python_version}}
path: ./.mypy_cache

- name: Run mypy
run: uv run -- mypy . # TODO: Add GitHub workflows output format

pre-commit:
runs-on: ubuntu-latest
pre-commit: # yamllint disable-line rule:key-ordering
env:
UV_NO_SYNC: true
UV_FROZEN: true
UV_NO_SYNC: true
UV_PYTHON_DOWNLOADS: never
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5

- name: Add GB Locale
run: |
sudo apt-get update
sudo apt-get install -y locales
sudo locale-gen en_GB.UTF-8
shell: bash

- name: Set Up Python
uses: actions/setup-python@v6
with:
Expand All @@ -82,39 +113,39 @@ jobs:
- name: Install pre-commit From Locked Dependencies
run: uv sync --only-group pre-commit

- name: Store Hashed Python Version
id: store-hashed-python-version
- id: store-hashed-python-version
name: Store Hashed Python Version
run: echo "hashed_python_version=$(uv run -- python -VV | sha256sum | cut -d' ' -f1)"
>> $GITHUB_OUTPUT

- uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit|${{steps.store-hashed-python-version.outputs.hashed_python_version}}|${{hashFiles('.pre-commit-config.yaml')}}
path: ~/.cache/pre-commit

- name: Setup pre-commit Environments
run: uv run -- pre-commit install-hooks

- name: Save pre-commit Checks Which Require Skipping
run: |
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == "${{ github.event.repository.default_branch }}" ]]; then
echo "SKIP=check-github-workflows,ruff,uv-lock,gitlint-ci" >> $GITHUB_ENV
echo "SKIP=check-github-workflows,ruff-check,uv-lock,gitlint-ci" >> $GITHUB_ENV
else
echo "SKIP=check-github-workflows,ruff,uv-lock" >> $GITHUB_ENV
fi

- name: Run pre-commit
run: uv run -- pre-commit run --all-files --hook-stage manual # TODO: Add GitHub workflows output format

- uses: pre-commit-ci/[email protected]
if: ${{!cancelled()}}
- if: ${{!cancelled()}}
uses: pre-commit-ci/[email protected]

pymarkdown:
runs-on: ubuntu-latest
pymarkdown: # yamllint disable-line rule:key-ordering
env:
UV_NO_SYNC: true
UV_FROZEN: true
UV_NO_SYNC: true
UV_PYTHON_DOWNLOADS: never
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5
Expand All @@ -135,15 +166,15 @@ jobs:
- name: Run PyMarkdown scan
run: uv run -- pymarkdown scan .

pytest:
needs: [uv-check]
runs-on: ubuntu-latest
permissions:
id-token: write
pytest: # yamllint disable-line rule:key-ordering
env:
UV_NO_SYNC: true
UV_FROZEN: true
UV_NO_SYNC: true
UV_PYTHON_DOWNLOADS: never
needs: [uv-check]
permissions:
id-token: write
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5
Expand All @@ -161,37 +192,37 @@ jobs:
- name: Install pytest From Locked Dependencies
run: uv sync --no-group dev --group test

- name: Store Hashed Python Version
id: store-hashed-python-version
- id: store-hashed-python-version
name: Store Hashed Python Version
run: echo "hashed_python_version=$(uv run -- python -VV | sha256sum | cut -d' ' -f1)"
>> $GITHUB_OUTPUT

- uses: actions/cache@v4
with:
path: ./.pytest_cache
key: pytest|${{steps.store-hashed-python-version.outputs.hashed_python_version}}
path: ./.pytest_cache

- name: Run pytest
run: uv run pytest --cov --cov-branch --cov-report=xml --junitxml=junit.xml

- name: Upload test results to Codecov
if: ${{ !cancelled() }}
- if: ${{ !cancelled() }}
name: Upload test results to Codecov
uses: codecov/test-results-action@v1
with:
use_oidc: true

- name: Upload coverage report to Codecov
- if: ${{ !cancelled() }}
name: Upload coverage report to Codecov
uses: codecov/codecov-action@v5
if: ${{ !cancelled() }}
with:
use_oidc: true

ruff-lint:
runs-on: ubuntu-latest
ruff-lint: # yamllint disable-line rule:key-ordering
env:
UV_NO_SYNC: true
UV_FROZEN: true
UV_NO_SYNC: true
UV_PYTHON_DOWNLOADS: never
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5
Expand All @@ -209,49 +240,48 @@ jobs:
- name: Install ruff From Locked Dependencies
run: uv sync --only-group lint-format

- name: Store Hashed Python Version
id: store-hashed-python-version
- id: store-hashed-python-version
name: Store Hashed Python Version
run: echo "hashed_python_version=$(uv run -- python -VV | sha256sum | cut -d' ' -f1)"
>> $GITHUB_OUTPUT

- uses: actions/cache@v4
with:
path: ./.ruff_cache
key: ruff|${{steps.store-hashed-python-version.outputs.hashed_python_version}}
path: ./.ruff_cache

- name: Run Ruff
run: uv run -- ruff check --no-fix --output-format=github

build-and-publish:
build-and-publish: # yamllint disable-line rule:key-ordering
env:
IMAGE_NAME: ${{github.repository}}
REGISTRY: ghcr.io
environment: publish
if: |
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == 'CSSUoB/TeX-Bot-Py-V2'
runs-on: ubuntu-latest
environment: publish
needs: [mypy, pre-commit, pymarkdown, pytest, ruff-lint, uv-check]
permissions:
contents: read
packages: write
attestations: write
contents: read
id-token: write

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{github.repository}}
packages: write
runs-on: ubuntu-latest

steps:
- name: Log in to the Container registry
uses: docker/[email protected]
with:
password: ${{secrets.GITHUB_TOKEN}}
registry: ${{env.REGISTRY}}
username: ${{github.actor}}
password: ${{secrets.GITHUB_TOKEN}}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Extract metadata (tags, labels) for Docker
id: docker-extract-metadata
- id: docker-extract-metadata
name: Extract metadata (tags, labels) for Docker
uses: docker/[email protected]
with:
images: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}
Expand All @@ -262,33 +292,32 @@ jobs:
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern=v{{major}},enable=${{!startsWith(github.ref, 'refs/tags/v0.')}}

- name: Build and Publish
id: build-and-publish
- id: build-and-publish
name: Build and Publish
uses: docker/build-push-action@v6
with:
labels: ${{steps.docker-extract-metadata.outputs.labels}}
push: true
tags: ${{steps.docker-extract-metadata.outputs.tags}}
labels: ${{steps.docker-extract-metadata.outputs.labels}}

- name: Generate Artifact Attestation
uses: actions/attest-build-provenance@v3
with:
subject-name: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}
subject-digest: ${{steps.build-and-publish.outputs.digest}}
push-to-registry: true
subject-digest: ${{steps.build-and-publish.outputs.digest}}
subject-name: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}

release:
release: # yamllint disable-line rule:key-ordering
if: github.ref_type == 'tag'
needs: [build-and-publish]
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write

if: github.ref_type == 'tag'
runs-on: ubuntu-latest

steps:
- name: Create GitHub Release
env:
env: # yamllint disable-line rule:key-ordering
GITHUB_TOKEN: ${{ github.token }}
run: gh release create '${{ github.ref_name }}' --repo '${{github.repository}}' --verify-tag
--generate-notes
23 changes: 12 additions & 11 deletions .github/workflows/pr-auto-updater.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
name: Automatic PR Updater
on:
push: {}

"on":
push: ~

jobs:
pr-auto-update:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
pull-requests: write
runs-on: ubuntu-latest

steps:
- name: Generate Access Token
- id: generate-token
name: Generate Access Token
uses: actions/create-github-app-token@v2
id: generate-token
with:
app-id: ${{ vars.PR_AUTO_UPDATE_CLIENT_ID }}
private-key: ${{ secrets.PR_AUTO_UPDATE_PRIVATE_KEY }}

- uses: CSSUoB/[email protected]
env:
env: # yamllint disable-line rule:key-ordering
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
PR_FILTER: 'labelled'
PR_LABELS: 'sync'
MERGE_CONFLICT_ACTION: 'label'
MERGE_CONFLICT_LABEL: 'conflict'
MERGE_CONFLICT_ACTION: label
MERGE_CONFLICT_LABEL: conflict
PR_FILTER: labelled
PR_LABELS: sync
9 changes: 4 additions & 5 deletions .github/workflows/prevent-migrations-deletion.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
name: Prevent Database Migration Files Deletion

on:
"on":
pull_request_target:
branches: [main]

jobs:
prevent-migrations-deletion:
runs-on: ubuntu-latest

permissions:
pull-requests: read
runs-on: ubuntu-latest

steps:
- name: Prevent migrations files being changed or deleted
uses: xalvarez/[email protected]
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
pattern: '.*\/db\/.+\/migrations\/\d{4}\w*\.py$'
allowNewFiles: true
githubToken: ${{ secrets.GITHUB_TOKEN }}
pattern: .*\/db\/.+\/migrations\/\d{4}\w*\.py$
Loading