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
10 changes: 10 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
coverage:
status:
project:
default:
target: auto
threshold: 0%
patch:
default:
target: auto
threshold: 0%
5 changes: 3 additions & 2 deletions .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
_commit: v0.12.1
_commit: v0.16.0
_src_path: https://github.com/mbercx/python-copier
description: Tools for running and parsing Quantum ESPRESSO calculations
coverage: codecov
doc_deploy: rtd
docs: mkdocs
package_name: qe-tools
type_check: loose
40 changes: 0 additions & 40 deletions .github/workflows/.ci.yml

This file was deleted.

48 changes: 48 additions & 0 deletions .github/workflows/cd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: cd

on:
push:
tags:
- 'v[0-9]*.[0-9]*.[0-9]*'

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install Hatch
run: pip install hatch

- name: Build sdist and wheel
run: hatch build

- name: Upload distributions
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

publish:
needs: build
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- name: Download distributions
uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
89 changes: 89 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: ci

on:
push:
branches:
- main
pull_request:

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install Hatch
run: pip install hatch

- name: Run pre-commit
run: hatch run pre-commit:run --all-files

commit-msgs:
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Check commit message format
run: |
base="${{ github.event.pull_request.base.sha }}"
head="${{ github.event.pull_request.head.sha }}"
fail=0
while IFS= read -r subject; do
msg=$(mktemp)
printf '%s\n' "$subject" > "$msg"
if ! python dev/check_commit_msg.py "$msg"; then
fail=1
fi
rm -f "$msg"
done < <(git log --format=%s "$base..$head")
exit $fail

tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.14']

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install hatch
- run: hatch test --cover

- name: Install coverage
if: '!cancelled()'
run: pip install coverage[toml]

- name: Coverage summary
if: '!cancelled()'
run: |
echo '## Test Coverage' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
coverage report >> $GITHUB_STEP_SUMMARY 2>&1 || true
echo '```' >> $GITHUB_STEP_SUMMARY

- name: Generate coverage XML
if: '!cancelled()'
run: coverage xml || true

- name: Upload coverage to Codecov
if: '!cancelled()'
uses: codecov/codecov-action@v5
with:
files: coverage.xml
fail_ci_if_error: false
80 changes: 80 additions & 0 deletions .github/workflows/copier-update.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: Copier Update

on:
schedule:
- cron: '0 5 * * 1'
workflow_dispatch:

permissions:
contents: write
pull-requests: write

jobs:
copier-update:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install copier
run: pip install copier

- name: Update from template
# --trust is required for non-interactive mode; it allows execution of
# any _tasks defined by the upstream template.
run: copier update --defaults --force --trust

- name: Check for changes
id: check
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "changed=true" >> $GITHUB_OUTPUT
else
echo "changed=false" >> $GITHUB_OUTPUT
fi

- name: Check for existing PR
if: ${{ steps.check.outputs.changed == 'true' }}

id: existing-pr
env:
GH_TOKEN: ${{ github.token }}
run: |
EXISTING=$(gh pr list --state open --json headRefName,number --jq '[.[] | select(.headRefName | startswith("copier-update/"))][0].number')
if [ -n "$EXISTING" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "::notice::Update PR #$EXISTING already exists, skipping."
else
echo "exists=false" >> $GITHUB_OUTPUT
fi

- name: Create PR
if: ${{ steps.check.outputs.changed == 'true' && steps.existing-pr.outputs.exists == 'false' }}

env:
GH_TOKEN: ${{ github.token }}
run: |
BRANCH="copier-update/${{ github.run_id }}"
git config user.name "copier-update[bot]"
git config user.email "copier-update[bot]@users.noreply.github.com"
git checkout -b "$BRANCH"
git add .
git commit -m "Update from copier template"
git push origin "$BRANCH"
gh pr create \
--title "Update from copier template" \
--body "Automated update from the upstream copier template.

This PR was created by the \`copier-update\` workflow.
Please review the changes carefully before merging.

> If there are conflicts or unexpected changes, you can run
> \`copier update\` locally to resolve them interactively."
31 changes: 21 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
repos:
- repo: local
hooks:
- id: mypy
name: Type-check with mypy
entry: mypy
language: python
types: [python]
require_serial: true
files: ^src/qe_tools/outputs/
default_install_hook_types: [pre-commit, commit-msg]

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.13.2
hooks:
Expand All @@ -19,3 +11,22 @@ repos:
- id: ruff-format
name: Format with Ruff
types_or: [ python, pyi ]

- repo: local
hooks:
- id: mypy
name: Type-check with mypy
entry: mypy
language: system
types: [ python ]
require_serial: true
files: ^src/

- repo: local
hooks:
- id: check-commit-msg
name: Check commit message format
entry: python dev/check_commit_msg.py
language: system
stages: [commit-msg]

59 changes: 59 additions & 0 deletions dev/check_commit_msg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""Validate that the commit subject starts with a recognized type emoji.

Convention: https://mbercx.github.io/python-copier/dev-standards/#specifying-the-type-of-change

Usage (called by pre-commit as a `commit-msg` hook):

python dev/check_commit_msg.py .git/COMMIT_EDITMSG
"""

import sys
from pathlib import Path

# Keep in sync with `dev/update_changelog.py` and `docs/dev-standards.md`.
# Listed in priority order (matches the dev-standards table).
VALID_EMOJIS: tuple[str, ...] = (
# Changelog sections
"πŸ’₯",
"πŸ“¦",
"❌",
"✨",
"πŸ‘Œ",
"πŸ›",
"πŸ“š",
# Developer sections
"πŸ”„",
"πŸ§ͺ",
"βͺ",
"πŸ”§",
"🧹",
# Excluded from changelog, but still valid types
"πŸš€",
"🐭",
"❓",
)


def main() -> int:
commit_msg_file = Path(sys.argv[1])
message = commit_msg_file.read_text(encoding="utf-8")

first_line = message.split("\n", maxsplit=1)[0]
if not first_line.startswith(VALID_EMOJIS):
print(
f"❌ Commit subject must start with a type emoji.\n"
f"\n"
f" Got: {first_line!r}\n"
f"\n"
f" Allowed: {' '.join(VALID_EMOJIS)}\n"
f"\n"
f" See: https://mbercx.github.io/python-copier/dev-standards/#specifying-the-type-of-change",
file=sys.stderr,
)
return 1

return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading
Loading