Workflows

This document details the CI/CD workflows and reusable actions to build and release Python applications. They run automated code quality checks to ensure code remains robust, maintainable, and testable.

The following actions can be referenced from other repositories using javidahmed64592/|repo_name|/actions/{category}/{action}@main.


Setup Actions

setup-uv-python

  • Description: Sets up Python with uv.

  • Location: setup-uv-python/action.yml

  • Steps:

    • Installs uv with caching enabled

    • Sets up Python using the version specified in .python-version

    • Caches dependencies based on uv.lock for faster builds

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/setup/setup-uv-python@main

install-python-core

  • Description: Installs core Python dependencies from pyproject.toml using uv.

  • Location: install-python-core/action.yml

  • Steps:

    • Uses the setup-uv-python action

    • Runs uv sync to install only core dependencies

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/setup/install-python-core@main

install-python-dev

  • Description: Installs dev Python dependencies from pyproject.toml using uv.

  • Location: install-python-dev/action.yml

  • Steps:

    • Uses the setup-uv-python action

    • Runs uv sync --extra dev to install core and dev dependencies

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/setup/install-python-dev@main

install-python-docs

  • Description: Installs documentation Python dependencies from pyproject.toml using uv.

  • Location: install-python-docs/action.yml

  • Steps:

    • Uses the setup-uv-python action

    • Runs uv sync --extra docs to install core and docs dependencies

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/setup/install-python-docs@main

check-tests-exists

  • Description: Check if the tests directory exists in the repository to conditionally execute test CI jobs.

  • Location: check-tests-exists/action.yml

  • Outputs:

    • exists: Indicates whether the tests directory exists

  • Steps:

    • Checks for directory named tests

    • Sets output to true or false based on directory existence

    • Logs message if directory doesn’t exist

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/setup/check-tests-exists@main
    id: check-tests

check-frontend-exists

  • Description: Check if the frontend directory exists in the repository to conditionally execute frontend CI and build jobs.

  • Location: check-frontend-exists/action.yml

  • Outputs:

    • exists: Indicates whether the frontend directory exists

  • Steps:

    • Checks for directory named <repository name>-frontend

    • Sets output to true or false based on directory existence

    • Logs message if directory doesn’t exist

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/setup/check-frontend-exists@main
    id: check-frontend-exists

setup-node

  • Description: Set up Node.js with npm cache and install dependencies.

  • Location: setup-node/action.yml

  • Steps:

    • Uses the setup-node action

    • Install npm packages

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/setup/setup-node@main

CI Actions

validate-pyproject

  • Description: Validate pyproject.toml structure.

  • Location: validate-pyproject/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Runs uv run validate-pyproject pyproject.toml to validate TOML structure

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/ci/validate-pyproject@main

ruff

  • Description: Run Ruff linting checks on the codebase.

  • Location: ruff/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Runs uv run -m ruff check to lint the code

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/ci/ruff@main

mypy

  • Description: Run Mypy type checking on the codebase.

  • Location: mypy/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Runs uv run -m mypy . to perform static type checking

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/ci/mypy@main

pytest

  • Description: Run Pytest tests with coverage reporting.

  • Location: pytest/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Runs uv run -m pytest --cov-report html --cov-report term to execute tests with coverage

    • Uploads HTML coverage report as artifact named backend-coverage-report

    • Fails if coverage drops below the threshold configured in pyproject.toml

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/ci/pytest@main

bandit

  • Description: Run Bandit security checks on the codebase.

  • Location: bandit/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Runs uv run bandit -r $PACKAGE_NAME -f json -o bandit-report.json to scan for security vulnerabilities

    • Uploads JSON report as artifact named bandit-report

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/ci/bandit@main

pip-audit

  • Description: Run pip-audit to check for known vulnerabilities in dependencies.

  • Location: pip-audit/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Runs uv run pip-audit --desc to check dependencies for known CVEs

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/ci/pip-audit@main

version-check

  • Description: Check version consistency across pyproject.toml and uv.lock.

  • Location: version-check/action.yml

  • Steps:

    • Uses the install-python-dev action

    • Extracts version from pyproject.toml using uv run ci-pyproject-version

    • Verifies uv.lock version matches using uv run ci-uv-lock-version

    • Verifies frontend version in package.json matches if frontend directory exists

    • Fails if any version mismatch is detected

Usage:

steps:
 - uses: javidahmed64592/actions-template-python/actions/setup/check-frontend-exists@main
   id: check-frontend-exists

  - uses: javidahmed64592/actions-template-python/actions/ci/version-check@main
    with:
      frontend-dir-exists: ${{ steps.check-frontend-exists.outputs.exists }}

frontend

  • Description: Runs frontend validation checks (type-checking, linting, formatting, testing) and uploads coverage reports.

  • Location: frontend/action.yml

  • Steps:

    • Uses the setup-node action

    • Runs npm run type-check for type checking

    • Runs npm run lint for static code analysis

    • Runs npm run format to tidy up scripts

    • Runs npm run test:coverage for frontend unit tests

    • Uploads unit test coverage report

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/ci/frontend@main

Build Actions

build-wheel

  • Description: Build Python wheel package and upload as artifact.

  • Location: build-wheel/action.yml

  • Steps:

    • Uses the install-python-core action

    • Runs uv build to create the wheel

    • Inspects wheel contents using unzip -l

    • Uploads wheel as artifact with name {PACKAGE_NAME}_wheel

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/build/build-wheel@main

verify-structure

  • Description: Download and verify the structure of the built wheel package.

  • Location: verify-structure/action.yml

  • Steps:

    • Uses the install-python-core action

    • Downloads the wheel artifact (named {PACKAGE_NAME}_wheel)

    • Installs the wheel using uv pip install

    • Verifies that site-packages and the package directory exist

    • Verifies the static directory exists if frontend is present

    • Optionally verifies additional directories specified in inputs

    • Fails if any required directory is missing

Usage:

steps:
 - uses: javidahmed64592/actions-template-python/actions/setup/check-frontend-exists@main
   id: check-frontend-exists

  - uses: javidahmed64592/actions-template-python/actions/build/verify-structure@main
    with:
      frontend-dir-exists: ${{ steps.check-frontend-exists.outputs.exists }}

Advanced usage with additional checks:

steps:
 - uses: javidahmed64592/actions-template-python/actions/setup/check-frontend-exists@main
   id: check-frontend-exists

  - uses: javidahmed64592/actions-template-python/actions/build/verify-structure@main
    with:
     frontend-dir-exists: ${{ steps.check-frontend-exists.outputs.exists }}
     expected-directories: |
       custom_directory_1
       custom_directory_2

build-frontend

  • Description: Build the frontend and upload the build artifacts for use in other jobs.

  • Location: build-frontend/action.yml

  • Steps:

    • Uses the setup-node action

    • Runs npm run build to build frontend static files

    • Uploads static files as build artifact

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/build/build-frontend@main

Docs Actions

build-docs

  • Description: Build Sphinx documentation and upload as artifact.

  • Location: build-docs/action.yml

  • Steps:

    • Uses the install-python-docs action

    • Runs uv run sphinx-build -M clean docs/source/ docs/build/ to clean previous builds

    • Runs uv run sphinx-build -M html docs/source/ docs/build/ to build HTML documentation

    • Uploads built documentation as artifact named documentation

Usage:

steps:
  - uses: javidahmed64592/actions-template-python/actions/docs/build-docs@main

publish-docs

  • Description: Deploy Sphinx documentation to GitHub Pages.

  • Location: publish-docs/action.yml

  • Outputs:

    • page_url: URL of the deployed GitHub Pages site

  • Steps:

    • Downloads the documentation artifact

    • Uploads HTML files to GitHub Pages

    • Deploys to GitHub Pages

    • Returns the deployed page URL as output

Usage:

steps:
  - id: publish
    uses: javidahmed64592/actions-template-python/actions/docs/publish-docs@main
  - run: echo "Deployed to ${{ steps.publish.outputs.page_url }}"

Docker Actions

build-start-services

  • Description: Creates .env file from .env.example and starts Docker Compose services.

  • Location: build-start-services/action.yml

  • Steps:

    • Moves .env.example to .env

    • Runs docker compose [build-args] up --build -d

    • Sleeps for wait-seconds to allow services to start

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/build-start-services@main
    with:
      wait-seconds: "5"
      build-args: ""

show-logs

  • Description: Shows logs from a Docker Compose container.

  • Location: show-logs/action.yml

  • Steps:

    • Displays logs using docker compose logs for the repository name

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/show-logs@main

check-containers

  • Description: Checks the server health by polling the /api/health endpoint.

  • Location: check-containers/action.yml

  • Steps:

    • Polls the server’s health endpoint at regular intervals until it returns a successful response or times out

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/check-containers@main
    with:
      port: 443
      num-retries: "5"
      timeout-seconds: "5"

stop-services

  • Description: Stops Docker Compose services and removes volumes and orphans.

  • Location: stop-services/action.yml

  • Steps:

    • Stops Docker Compose services and removes volumes and orphans

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/stop-services@main

prepare-release

  • Description: Gets the package version, creates a release directory with essential files, builds a tarball, and uploads it as a workflow artifact.

  • Location: prepare-release/action.yml

  • Steps:

    • Extracts version via uv run ci-pyproject-version

    • Creates release directory and copies docker-compose.yml, README.md, LICENSE, .env.example

    • Creates compressed tarball

    • Uploads tarball as artifact named {PACKAGE_NAME}_release

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/prepare-release@main

check-repo-name

  • Description: Compares the repository name against the package name in pyproject.toml to prevent template-derived repositories from accidentally publishing releases.

  • Location: check-repo-name/action.yml

  • Outputs:

    • should_release - "true" if names match, "false" otherwise

    • package_name - Package name extracted from pyproject.toml

  • Steps:

    • Extracts package name via uv run ci-pyproject-name

    • Compares repository name with package name

    • Sets outputs based on match result and package name

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/check-repo-name@main
    id: check_repo_name

get-version

  • Description: Extracts the version and tag from pyproject.toml.

  • Location: get-version/action.yml

  • Outputs:

    • version - Version string (e.g. 1.2.3)

    • tag - Version tag (e.g. v1.2.3)

  • Steps:

    • Extracts version via uv run ci-pyproject-version

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/get-version@main
    id: get_version

check-tag

  • Description: Checks if a Git tag already exists for the given version to avoid duplicate releases.

  • Location: check-tag/action.yml

  • Outputs:

    • tag_exists - "true" if the tag exists, "false" otherwise

  • Steps:

    • Checks if tag exists using GitHub API

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/check-tag@main
    id: check_tag
    with:
      tag: ${{ steps.get_version.outputs.tag }}

generate-release-notes

  • Description: Substitutes placeholders in RELEASE-NOTES.md with actual values.

  • Location: generate-release-notes/action.yml

  • Inputs:

    • version - Release version (without the v prefix)

    • package_name - Package name from pyproject.toml

  • Steps:

    • Substitutes {{VERSION}}, {{PACKAGE_NAME}}, and {{REPOSITORY}} placeholders

    • Repository is derived from GitHub context

Usage:

steps:
  - uses: javidahmed64592/python-template-server/.github/actions/docker/generate-release-notes@main
    with:
      version: ${{ steps.get_version.outputs.version }}
      package_name: ${{ steps.check_repo_name.outputs.package_name }}