Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Default code owners
* @d-hickey @pohuigin
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: "uv"
directory: "/backend/"
schedule:
interval: "monthly"
open-pull-requests-limit: 20

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
open-pull-requests-limit: 20
48 changes: 48 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# File types
documentation:
- changed-files:
- any-glob-to-any-file: ['**/*.md', '**/*.mdx']

localization:
- changed-files:
- any-glob-to-any-file: ['**/localization/**/*']

test:
- changed-files:
- any-glob-to-any-file: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts', '**/*.spec.tsx']


# Languages
python:
- changed-files:
- any-glob-to-any-file: ['**/*.py']

typescript:
- changed-files:
- any-glob-to-any-file: ['**/*.ts']

react:
- changed-files:
- any-glob-to-any-file: ['**/*.tsx']

c-sharp:
- changed-files:
- any-glob-to-any-file: ['**/*.cs']

yaml:
- changed-files:
- any-glob-to-any-file: ['**/*.yml']


# Functional areas
backend:
- changed-files:
- any-glob-to-any-file: ['backend/**/*']

frontend:
- changed-files:
- any-glob-to-any-file: ['frontend/**/*']

github actions:
- changed-files:
- any-glob-to-any-file: ['.github/**/*']
8 changes: 8 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## What?

...

For more background, see ticket
#L3D-123.

## Testing
25 changes: 25 additions & 0 deletions .github/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
changelog:
categories:
- title: 🚨 Breaking Changes
labels:
- breaking change

- title: ✨ Features
labels:
- feature

- title: 🐛 Bugs
labels:
- bug

- title: 📋 Tasks
labels:
- task

- title: 📑 Change Requests
labels:
- CR

- title: 📦 Other Changes
labels:
- "*"
76 changes: 76 additions & 0 deletions .github/workflows/backend_validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Backend Build, Lint, and Test

on:
workflow_call:

# Allow manual trigger
workflow_dispatch:

jobs:
build:
name: Build and Test
# Switching to self-hosted runner from `runs-on: ubuntu-latest`
# TEMP: runner filtering (we prob need new dedicated runners):
runs-on: [ubuntu-latest]
defaults:
run:
working-directory: ./backend
# Don't run the job if the PR is a draft PR
if: ${{ !github.event.pull_request.draft }}

services:
postgres:
image: postgres:alpine
env:
POSTGRES_USER: ${{ env.PROCRASTINATE_DB_USER }}
POSTGRES_DB: ${{ env.PROCRASTINATE_DB_NAME }}
POSTGRES_PASSWORD: ${{ env.PROCRASTINATE_DB_PASSWORD }}
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

env:
PROCRASTINATE_DB_USER: db_admin
PROCRASTINATE_DB_NAME: shredder_procrastinate_db
PROCRASTINATE_DB_PASSWORD: db_password
# Determine whether the workflow was triggered by merge queue
MERGE_QUEUE: ${{ github.event_name == 'merge_group' }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 1

- name: Setup Python
uses: astral-sh/setup-uv@v8.0.0
with:
enable-cache: true
cache-dependency-glob: "./pyproject.toml"
working-directory: "./backend"
prune-cache: false

- name: Build
run: |
cp .env.example .env
make env
make build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any

- name: Lint
id: run-lint
run: |
make lint

- name: Run Tests with Coverage
run: |
make test-cov

- name: Coverage threshold (warn only)
continue-on-error: true
run: |
COVERAGE_FILE=.pytest_coverage ~/.local/bin/uv run coverage report --fail-under=80
20 changes: 20 additions & 0 deletions .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This workflow will triage pull requests and apply a label based on the
# paths that are modified in the pull request.
#
# To use this workflow, you will need to set up a .github/labeler.yml
# file with configuration. For more information, see:
# https://github.com/actions/labeler

name: "PR Labeler 🏷️"
on: [pull_request]

jobs:
triage:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v6
with:
sync-labels: true
22 changes: 22 additions & 0 deletions .github/workflows/lint-actions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This workflow will lint github actions workflows
# on pull requests that modify the .github directory.

name: "Workflow linter 🧹"
on:
workflow_call:

jobs:
lint:
name: Lint Workflows
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 1
- uses: actions/setup-go@v5
with:
go-version: "1.24.0" # The Go version to download (if necessary) and use.
cache: true
- run: go install github.com/rhysd/actionlint/cmd/actionlint@latest
- run: actionlint
61 changes: 61 additions & 0 deletions .github/workflows/pull_request_verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Verify Changes

# This workflow will run on PR open or update
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
merge_group:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
paths:
runs-on: ubuntu-latest
permissions:
pull-requests: read
actions: read
contents: read
# Set job outputs to values from filter step
outputs:
backend: ${{ steps.filter.outputs.backend }}
lint_actions: ${{ steps.filter.outputs.lint_actions }}
steps:
- name: Checkout code
if: github.event_name == 'merge_group' # Run only for merge queue
uses: actions/checkout@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}

- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
backend:
- "backend/**"
lint_actions:
- ".github/**"

# Verify Backend
backend:
needs: paths
uses: ./.github/workflows/backend_validate.yml
if: ${{ needs.paths.outputs.backend == 'true' }}

# Verify Workflows
lint_actions:
needs: paths
if: ${{ needs.paths.outputs.lint_actions == 'true' }}
uses: ./.github/workflows/lint-actions.yml

# Verify All Passed
verify_all_passed:
needs: [backend, lint_actions]
runs-on: ubuntu-latest
if: ${{ always() && (failure() || cancelled()) }}
steps:
- name: Fail job
uses: actions/github-script@v8.0.0
with:
script: core.setFailed('Some checks failed or cancelled.')
72 changes: 72 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Release Backend

on:
workflow_call:
inputs:
environment:
required: true
type: string

jobs:
build-and-push:
environment: ${{ inputs.environment }}
name: Backend Release to GitHub
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
defaults:
run:
working-directory: ./backend

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 1

- name: Generate .env file
run: |
cp .env.example .env

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

- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker (app)
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/propylon/${{ github.repository }}/backend

- name: Build and push Docker image (app)
uses: docker/build-push-action@v7
with:
context: ./backend/.
file: ./backend/Dockerfile
target: migrate_stage
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Extract metadata (tags, labels) for Docker (worker)
id: meta-worker
uses: docker/metadata-action@v6
with:
images: ghcr.io/propylon/${{ github.repository }}/backend-worker

- name: Build and push Docker image (worker)
uses: docker/build-push-action@v7
with:
context: ./backend/.
file: ./backend/Dockerfile
target: worker_stage
push: true
tags: ${{ steps.meta-worker.outputs.tags }}
labels: ${{ steps.meta-worker.outputs.labels }}
36 changes: 36 additions & 0 deletions backend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Deploy
DEBUG=1
ENV_TYPE=local
SERVICE_NAME=shredder_app

# Build
PYTHON_VERSION=3.13
PYTHONPATH=./shredder/src
ENV_DIR=.venv
UV_PROJECT_ENVIRONMENT=${ENV_DIR}

# Docker
DOCKER_COMPOSE_PROJECT=shredder
COMPOSE_ENV_FILES=.env
DOCKER_NETWORK_NAME=backend

# Procrastinate
PROCRASTINATE_APP=shredder.app
PROCRASTINATE_WORKER=shredder_worker
PROCRASTINATE_TASK_PATHS=shredder.tasks
PROCRASTINATE_QUEUE=shredder_queue
# Specify how many jobs are handled at once by the Procrastinate worker
# (depends on max threads and also how much downtime is expected in the job flow: I/O, network latency, etc.)
PROCRASTINATE_CONCURRENCY=4
# Seconds. Maximum time a job is allowed to run before being force-failed
PROCRASTINATE_MAX_JOB_TTL=600
# Postgres DB Connection
PROCRASTINATE_DB_HOST=127.0.0.1
PROCRASTINATE_DB_PORT=5432
PROCRASTINATE_DB_NAME=shredder_procrastinate_db
# UPDATE ME:
PROCRASTINATE_DB_USER=db_admin
PROCRASTINATE_DB_PASSWORD=db_password

# PDF2HTMLEX settings (optional)
SHREDDER_CONVERSION_CONFIG=--embed-css,0,--css-filename,pages.css,--embed-outline,1,--process-annotation,1,--decompose-ligature,1,--bg-format,svg
Loading
Loading