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
16 changes: 16 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.git
.github
.claude
.venv
__pycache__
*.pyc
.pytest_cache
.mypy_cache
.ruff_cache
.coverage
htmlcov
site
dist
.dockerignore
Dockerfile
docker-compose.yml
109 changes: 24 additions & 85 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,96 +1,35 @@
name: CI
name: hier-config-api build and test

on:
push:
branches: [ main, develop ]
branches: [develop, next]
pull_request:
branches: [ main, develop ]
branches: [develop, next]

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 2.3.1
virtualenvs-create: true
virtualenvs-in-project: true

- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root

- name: Install project
run: poetry install --no-interaction

- name: Run Ruff linter
run: poetry run ruff check .

- name: Run Ruff formatter check
run: poetry run ruff format --check .

- name: Run mypy
run: poetry run mypy hier_config_api

test:
name: Test (Python ${{ matrix.python-version }})
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]

python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 2.3.1
virtualenvs-create: true
virtualenvs-in-project: true

- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root

- name: Install project
run: poetry install --no-interaction

- name: Run tests
run: poetry run pytest --cov=hier_config_api --cov-report=xml --cov-report=term-missing

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
if: matrix.python-version == '3.11'
with:
file: ./coverage.xml
fail_ci_if_error: false
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install poetry
uses: snok/install-poetry@v1
with:
version: 2.3.1
- name: Run tests
run: |
poetry install --no-interaction
poetry run python scripts/build.py lint
poetry run python scripts/build.py pytest --coverage
12 changes: 7 additions & 5 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ name: Deploy Documentation
on:
push:
branches:
- main
- develop
- next
pull_request:
branches:
- main
- develop
- next

permissions:
contents: write
Expand All @@ -20,7 +22,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
python-version: "3.12"

- name: Install Poetry
uses: snok/install-poetry@v1
Expand All @@ -44,10 +46,10 @@ jobs:
run: poetry install --no-interaction

- name: Build documentation
run: poetry run mkdocs build
run: poetry run mkdocs build --strict

- name: Deploy to GitHub Pages
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Prepare Release

# The branch to release from is chosen via the standard "Run workflow"
# branch dropdown in the GitHub UI — this workflow runs against, and
# releases from, whatever ref it was dispatched on.
on:
workflow_dispatch:
inputs:
bump:
description: Version bump type
required: true
type: choice
options:
- major
- minor
- patch
- prerelease

permissions:
contents: write
pull-requests: write

jobs:
prepare:
runs-on: ubuntu-latest
steps:
- name: Require repository admin
uses: actions/github-script@v8
with:
script: |
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.actor,
});
if (data.permission !== 'admin') {
core.setFailed(
`@${context.actor} has '${data.permission}' permission; ` +
'only repository admins may prepare a release.',
);
}
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install poetry
uses: snok/install-poetry@v1
with:
version: 2.3.1
- name: Bump version
id: bump
run: |
poetry version "${{ github.event.inputs.bump }}"
version="$(poetry version --short)"
echo "version=${version}" >> "$GITHUB_OUTPUT"
case "$version" in
*a*|*b*|*rc*|*dev*) echo "prerelease=true" >> "$GITHUB_OUTPUT" ;;
*) echo "prerelease=false" >> "$GITHUB_OUTPUT" ;;
esac
- name: Commit bump to release branch
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "release/v${{ steps.bump.outputs.version }}"
git commit -am "chore(release): prepare ${{ steps.bump.outputs.version }}"
git push origin "release/v${{ steps.bump.outputs.version }}"
- name: Open release pull request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr create \
--base "${{ github.ref_name }}" \
--head "release/v${{ steps.bump.outputs.version }}" \
--title "chore(release): prepare ${{ steps.bump.outputs.version }}" \
--body "Bumps the version to ${{ steps.bump.outputs.version }} (bump type: ${{ github.event.inputs.bump }}).

Merge this PR first, then publish the draft release v${{ steps.bump.outputs.version }} to trigger the PyPI publish."
- name: Create draft GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
args=()
if [ "${{ steps.bump.outputs.prerelease }}" = "true" ]; then
args+=(--prerelease)
fi
gh release create "v${{ steps.bump.outputs.version }}" \
--target "${{ github.ref_name }}" \
--draft \
--title "v${{ steps.bump.outputs.version }}" \
--generate-notes \
"${args[@]}"
29 changes: 29 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Release

# Fires when a release is published, including a draft release being
# published (the `created` type never fires for drafts).
on:
release:
types: [published]

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
steps:
# On release events, checkout defaults to the release's tag ref.
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install poetry
uses: snok/install-poetry@v1
with:
version: 2.3.1
- name: Publish to PyPI
run: |
poetry config pypi-token.pypi "${{ secrets.PYPI_TOKEN }}"
poetry publish --build
39 changes: 39 additions & 0 deletions .github/workflows/sync-standards.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: hier-config-api sync standards

on:
schedule:
# Weekly, Monday 06:00 UTC
- cron: "0 6 * * 1"
workflow_dispatch:

jobs:
sync:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install poetry
uses: snok/install-poetry@v1
with:
version: 2.3.1
- name: Apply canonical standards
run: |
poetry install --no-interaction
poetry run python scripts/sync_standards.py apply
- name: Open pull request if standards drifted
uses: peter-evans/create-pull-request@v7
with:
branch: sync-standards
base: develop
title: Sync development standards from netdevops/hier_config
commit-message: Sync development standards from netdevops/hier_config
body: >
Automated update of shared development-standard files from the
canonical repository declared in `.standards.yml`. Review CI
results and reconcile any incompatibilities before merging.
19 changes: 5 additions & 14 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
os: ubuntu-24.04
tools:
python: "3.12"
jobs:
post_create_environment:
# Install poetry
- pip install poetry
post_install:
# Install dependencies with poetry
- poetry install --with dev
# Install the project and all dependency groups into the Read the Docs
# virtualenv (VIRTUAL_ENV must point at it, otherwise poetry installs
# into its own virtualenv and mkdocs is not found at build time)
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with dev

# Build documentation with MkDocs
mkdocs:
configuration: mkdocs.yml

# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- method: pip
path: .
- requirements: docs/requirements.txt
20 changes: 20 additions & 0 deletions .standards.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Shared development standards for netdevops hier-config projects.
#
# The files listed below are owned by the canonical repository and kept in
# sync across all hier-config projects. Use `invoke sync-standards` (or
# `poetry run python scripts/sync_standards.py check|apply`) to compare the
# local copies against the canonical versions and pull in upstream changes.
source:
repo: netdevops/hier_config
ref: master

# Whole-word replacements applied to fetched file contents so package
# references match this project.
substitutions:
hier_config: hier_config_api

files:
- scripts/build.py
- scripts/sync_standards.py
- .yamllint.yml
- .dockerignore
Loading
Loading