Skip to content

Commit

Permalink
ci: Update CI/CD toolchain for uv and git-cliff
Browse files Browse the repository at this point in the history
  • Loading branch information
seandstewart committed Feb 8, 2025
1 parent 7122300 commit 03c37a1
Show file tree
Hide file tree
Showing 14 changed files with 2,213 additions and 2,176 deletions.
13 changes: 6 additions & 7 deletions .github/actions/bootstrap-environ/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ inputs:
runner:
description: The Runner to build your environment on.

env:
# Configure a relative location for the uv cache
UV_CACHE_DIR: ~/.cache/uv

runs:
using: composite
steps:
Expand All @@ -15,17 +19,12 @@ runs:
git config user.email [email protected]
git config pull.ff true
shell: bash
- uses: actions/setup-python@v5
- uses: astral-sh/setup-uv@v5
with:
python-version: ${{ inputs.python-version }}
- uses: Gr1N/setup-poetry@v8
- uses: actions/cache@v4
with:
path: ~/.cache/
key: ${{ inputs.runner }}|${{ inputs.python-version }}|${{ hashFiles('poetry.lock') }}|${{ hashFiles('.pre-commit-config.yaml') }}
- run: poetry --version
shell: bash
key: ${{ inputs.runner }}|${{ inputs.python-version }}|${{ hashFiles('uv.lock') }}|${{ hashFiles('.pre-commit-config.yaml') }}
- run: make install
shell: bash
- run: poetry env info
shell: bash
2 changes: 1 addition & 1 deletion .github/workflows/.build-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
python-version: ${{ inputs.python-version }}
runner: ${{ inputs.runner }}
- name: Build ${{ inputs.runner }} binaries
run: poetry build
run: uv build
- name: Store dist artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
10 changes: 1 addition & 9 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ jobs:
python-version: 3.x
runner: ubuntu-latest
- name: Compile Release Notes
run: make release-notes > release-notes.md
run: make release-notes
- name: Report Version
run: |
export "RELEASE_VERSION=v$(make report-version)";
Expand All @@ -116,11 +116,3 @@ jobs:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
body_path: release-notes.md
tag_name: ${{ github.env.RELEASE_VERSION }}
target_commitish: ${{ github.env.TARGET_COMMITISH }}
make_latest: true
files: dist/*
24 changes: 8 additions & 16 deletions .github/workflows/tag.yml → .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
name: Trigger Release
name: Create Tag

on:
workflow_dispatch:
inputs:
level:
description: "The level to bump the current version"
required: true
default: "patch"
options:
- "patch"
- "minor"
- "major"
- "prepatch"
- "preminor"
- "prerelease"
push:
branches:
- 'main'
tags-ignore:
- '**'

defaults:
run:
Expand All @@ -26,7 +18,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-latest ]
python-version: [ "3.9" ]
python-version: [ "3.12" ]
steps:
- uses: actions/create-github-app-token@v1
id: app-token
Expand All @@ -42,6 +34,6 @@ jobs:
python-version: ${{ matrix.python-version }}
runner: ${{ matrix.os }}
- name: Tag New Version
run: make release-version rule=${{ inputs.level }}
run: make release-version
- name: Push New Version
run: git push --follow-tags origin ${{ github.ref_name }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,4 @@ venv.bak/
/benchmark/.cases.json
*.DS_Store
coverage.db
release-notes.md
20 changes: 17 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.6.3
rev: v0.9.4
hooks:
# Run the linter.
- id: ruff
types_or: [ python, pyi ]
args: [ --fix, --config=pyproject.toml ]
stages: [ pre-commit, manual ]
# Run the formatter.
- id: ruff-format
types_or: [ python, pyi ]
args: [ --config=pyproject.toml ]
stages: [ pre-commit, manual ]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.2
rev: v1.14.1
hooks:
- id: mypy
args: [ --config-file=pyproject.toml ]
Expand All @@ -23,9 +25,21 @@ repos:
- types-typed-ast
- types-orjson
files: "src/.*"
stages: [ pre-commit, manual ]
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v3.4.0
rev: v4.0.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
args: []
- repo: https://github.com/astral-sh/uv-pre-commit
# uv version.
rev: 0.5.26
hooks:
- id: uv-sync
args: ["--locked", "--all-packages"]
stages:
- pre-commit
- post-checkout
- post-merge
- post-rewrite
55 changes: 23 additions & 32 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,25 @@ SHELL := bash
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules

ifeq ($(VIRTUAL_ENV), )
RUN_PREFIX := poetry run
else
RUN_PREFIX :=
endif

RUN_PREFIX := uv run --

# region: environment

bootstrap: setup-poetry update install ## Bootstrap your local environment for development.
quickstart: setup-uv install ## Bootstrap your local environment for development.
.PHONY: bootstrap

setup-poetry: ## Set up your poetry installation and ensure it's up-to-date.
@poetry self update -q
.PHONY: setup-poetry
setup-uv: ## Set up your poetry installation and ensure it's up-to-date.
@curl -LsSf https://astral.sh/uv/install.sh | sh
@uv self update
.PHONY: setup-uv

install: ## Install or re-install your app's dependencies.
@poetry install
@uv sync --all-extras --dev --locked
@$(RUN_PREFIX) pre-commit install && $(RUN_PREFIX) pre-commit install-hooks
.PHONY: install

update: ## Update app dependencies
@poetry update
@uv sync --all-extras --dev
@$(RUN_PREFIX) pre-commit autoupdate
.PHONY: update

Expand All @@ -40,17 +36,11 @@ ifneq ($(target), .)
files := --files=$(target)
endif

format: ## Manually run code-formatters for the app.
@$(RUN_PREFIX) pre-commit run ruff-format $(files)
@$(RUN_PREFIX) pre-commit run ruff $(files)
.PHONY: format

# endregion
# region: ci

lint: ## Run this app's linters. Target a specific file or directory with `target=path/...`.
@$(RUN_PREFIX) pre-commit run ruff $(files)
@$(RUN_PREFIX) pre-commit run mypy $(files)
@$(RUN_PREFIX) pre-commit run --hook-stage=manual $(files)
.PHONY: lint

test: ## Run this app's tests with a test db. Target a specific path `target=path/...`.
Expand All @@ -63,41 +53,42 @@ rule ?= patch


release-version: ## Bump the version for this package.
$(eval current_version := $(shell poetry version -s))
$(eval new_version := $(shell poetry version -s $(rule)))
$(eval message := "Release $(current_version) -> $(new_version)")
git add pyproject.toml
git commit -m $(message)
git tag -a v$(new_version) -m $(message)
$(eval message := "Release $(next_version)")
#git tag -a $(next_version) -m $(message)
.PHONY: release-version


BUMP_CMD := git-cliff --bumped-version -o -

report-version: ## Show the current version of this library.
@$(VERSION_CMD)
@echo $(version)
.PHONY: report-version

docs-version: ## Show the current version of this library as applicable for documentation.
@$(VERSION_CMD) | $(SED_CMD) $(DOCS_FILTER)
@echo $(docs_version)
.PHONY: docs-version

docs: ## Build the versioned documentation
@$(RUN_PREFIX) mike deploy -u --push $(version) $(alias)
.PHONY: docs

VERSION_CMD ?= poetry version -s
VERSION_CMD ?= hatchling version
SED_CMD ?= sed -En
CI_FILTER ?= 's/^([[:digit:]]+.[[:digit:]]+.[[:digit:]]+).*$$/v\1/p'
DOCS_FILTER ?= 's/^([[:digit:]]+.[[:digit:]]+).*$$/v\1/p'
version ?= $(shell $(VERSION_CMD) | $(SED_CMD) $(DOCS_FILTER))
version ?= $(shell $(RUN_PREFIX) $(VERSION_CMD) | $(SED_CMD) $(CI_FILTER))
docs_version ?= $(shell $(RUN_PREFIX) $(VERSION_CMD) | $(SED_CMD) $(DOCS_FILTER))
next_version ?= $(shell $(RUN_PREFIX) $(BUMP_CMD))
alias ?= latest

changelog: ## Compile the latest changelog for the current branch.
@$(RUN_PREFIX) git-changelog
@$(RUN_PREFIX) git-cliff --bump
@git add docs/changelog.md
@git commit -m "[skip ci] Update changelog." --allow-empty
@git commit -m "[git-cliff] Update changelog." --allow-empty
.PHONY: changelog

release-notes: ## Compile release notes for VCS
@$(RUN_PREFIX) git-changelog --release-notes
@$(RUN_PREFIX) git-cliff --bump --unreleased -o release-notes.md
.PHONY: release-notes

# endregion
Expand Down
121 changes: 121 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# git-cliff ~ default configuration file
# https://git-cliff.org/docs/configuration
#
# Lines starting with "#" are comments.
# Configuration options are organized into tables and keys.
# See documentation for more information on available options.

[remote.github]
owner = "seandstewart"
repo = "python-typelib"

[bump]
features_always_bump_minor = false
breaking_always_bump_major = false

[changelog]
# template for the changelog header
header = """
# Changelog\n
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n
"""
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
{%- macro remote_url() -%}
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}
{%- macro version_ref() -%}
[{{ version | trim_start_matches(pat="v") }}][{{ version | trim_start_matches(pat="v") }}]
{%- endmacro -%}
{% if version -%}
## {{ self::version_ref() }} - {{ timestamp | date(format="%Y-%m-%d") }}
{% else -%}
## [Unreleased][unreleased]
{% endif -%}
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{%- for commit in commits %}
- {{ commit.message | split(pat="\n") | first | upper_first | trim }}\
{% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
{% if commit.remote.pr_number %} in \
[#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
{%- endif -%}
{% endfor %}
{% endfor %}
{%- if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
## New Contributors
{%- endif -%}
{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
* @{{ contributor.username }} made their first contribution
{%- if contributor.pr_number %} in \
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
{%- endif %}
{%- endfor %}\n\n
"""
# template for the changelog footer
footer = """
{%- macro remote_url() -%}
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}
{% for release in releases -%}
{% if release.version -%}
{% if release.previous.version -%}
[{{ release.version | trim_start_matches(pat="v") }}]: \
{{ self::remote_url() }}/compare/{{ release.previous.version }}..{{ release.version }}
{% endif -%}
{% else -%}
[unreleased]: {{ self::remote_url() }}/compare/{{ release.previous.version }}..HEAD
{% endif -%}
{% endfor %}
<!-- generated by git-cliff -->
"""
# remove the leading and trailing whitespace from the templates
trim = true
output = "docs/changelog.md"

[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = true
# filter out the commits that are not conventional
filter_unconventional = true
# process each line of a commit as an individual commit
split_commits = false
# regex for preprocessing the commit messages
commit_preprocessors = [
# Replace issue numbers
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
]
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
{ message = "^chore\\(release\\): prepare for", skip = true },
{ message = "^chore\\(deps.*\\)", skip = true },
{ message = "^chore\\(pr\\)", skip = true },
{ message = "^chore\\(pull\\)", skip = true },
{ message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
{ message = ".*", group = "<!-- 10 -->💼 Other" },
]
# filter out the commits that are not matched by commit parsers
filter_commits = false
# sort the tags topologically
topo_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "oldest"
Loading

0 comments on commit 03c37a1

Please sign in to comment.