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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
26 changes: 26 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Codecov configuration
# https://docs.codecov.com/docs/codecov-yaml

github_checks:
annotations: true

comment:
layout: 'reach, diff, flags, files'
behavior: default
require_changes: false
require_base: false
require_head: true

coverage:
status:
project:
default:
target: auto
threshold: 1%
# Make project coverage informational (won't block PR)
informational: true
patch:
default:
target: auto
# Require patch coverage but with threshold
threshold: 1%
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WARNING: Do not edit this file manually.
# Any changes will be overwritten by Copier.
_commit: v0.11.0-7-gb5113cf
_commit: v0.11.4
_src_path: gh:easyscience/templates
app_docs_url: https://easyscience.github.io/diffraction-app
app_doi: 10.5281/zenodo.18163581
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup-pixi/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ inputs:
runs:
using: 'composite'
steps:
- uses: prefix-dev/setup-pixi@v0.9.4
- uses: prefix-dev/setup-pixi@v0.9.5
with:
environments: ${{ inputs.environments }}
activate-environment: ${{ inputs.activate-environment }}
Expand Down
67 changes: 49 additions & 18 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
- One class per file when substantial; group small related classes.
- No `**kwargs` — use explicit keyword arguments.
- No string-based dispatch (e.g. `getattr(self, f'_{name}')`); write
named methods (`_set_sample_form`, `_set_beam_mode`).
named methods (`_set_sample_form`, `_set_beam_mode`). Narrow framework
metadata lookups are allowed when the attribute name is a class-level
declaration, is not user input, and is validated in one central place;
for example, `CategoryItem._category_entry_name`.
- Public attrs are either editable (getter+setter property) or read-only
(getter only). For internal mutation of read-only props, use a private
`_set_<name>` method, not a public setter.
Expand Down Expand Up @@ -77,7 +80,7 @@
## Testing

- Every new module, class, or bug fix ships with tests. See
`docs/architecture/architecture.md` §10 for the full strategy.
`docs/dev/adrs/accepted/test-strategy.md` for the full strategy.
- Unit tests mirror the source tree:
`src/easydiffraction/<pkg>/<mod>.py` →
`tests/unit/easydiffraction/<pkg>/test_<mod>.py`. Verify with
Expand All @@ -102,8 +105,11 @@

- Before any structural/design change (new categories, factories,
switchable-category wiring, datablocks, CIF serialisation), read
`docs/architecture/architecture.md` and follow documented patterns.
Localised bug fixes or test updates need only this file.
`docs/dev/adrs/index.md` and the relevant accepted ADRs. Localised bug
fixes or test updates need only this file.
- Development documentation lives under `docs/dev/`. Use
`docs/dev/adrs/index.md` as the architecture and decision navigation
surface; there is no separate `architecture.md` source of truth.
- Project is in beta: no legacy shims, no deprecation warnings — update
tests and tutorials to the current API.
- Minimal diffs; don't reformat working code. Fix only what's asked;
Expand All @@ -112,7 +118,10 @@
resolves them.
- Never remove or replace existing functionality without explicit
confirmation — highlight every removal and wait for approval.
- When renaming, grep the entire project (code, tests, tutorials, docs).
- When renaming or auditing usages, search the entire project (code,
tests, tutorials, docs). Use `git grep -n` because all contributors
have Git; do not assume `rg` is installed. If `git grep` is
unavailable, fall back to `find ... -type f` plus `grep -n`.
- Each change is atomic and single-commit-sized: make one change,
suggest the commit message, then stop and wait for confirmation.
- When in doubt, ask.
Expand All @@ -137,35 +146,51 @@

Non-trivial changes use a two-phase workflow:

- **Phase 1 — Implementation.** Code, docs, and architecture updates
only. Do not create or run tests unless the user explicitly asks. When
done, present for review and iterate until approved.
- **Phase 1 — Implementation.** Code and docs updates only. Update ADRs
when the change affects architecture or documented decisions. Do not
create or run tests unless the user explicitly asks. When done,
present for review and iterate until approved.
- **Phase 2 — Verification.** Add/update tests, then run `pixi run fix`,
`pixi run check`, `pixi run unit-tests`, `pixi run integration-tests`,
`pixi run script-tests`.

Notes:

- `pixi run fix` regenerates `docs/architecture/package-structure-*.md`
automatically — never edit those by hand. Don't review auto-fixes;
accept and move on. Then `pixi run check` until clean.
- `pixi run fix` regenerates `docs/dev/package-structure/full.md` and
`docs/dev/package-structure/short.md` automatically — never edit those
by hand. Don't review auto-fixes; accept and move on. Then
`pixi run check` until clean.
- When a check command needs saved output for analysis, capture the log
and preserve the command exit code with a zsh-safe variable name:
`pixi run check > /tmp/easydiffraction-check.log 2>&1; check_exit_code=$?; tail -n 200 /tmp/easydiffraction-check.log; exit $check_exit_code`.
Never assign to `status` in zsh; it is readonly. Use task-specific
names such as `check_exit_code`, `unit_tests_exit_code`, or
`script_tests_exit_code`.
- Open issues / design questions / planned improvements live in
`docs/architecture/issues_open.md` (priority-ordered). On resolution,
move to `docs/architecture/issues_closed.md` and update
`architecture.md` if affected.
`docs/dev/issues/open.md` (priority-ordered). On resolution, move to
`docs/dev/issues/closed.md` and update the relevant ADR or
`docs/dev/adrs/index.md` if affected.

### Planning

When asked to create a plan:

- Start the plan by referencing this file:
`.github/copilot-instructions.md`. State any deliberate exception to
these instructions in the plan itself.
- First gather enough repository context to make the plan concrete. Ask
all ambiguous or unclear questions in one concise batch; record
unresolved questions in the plan if the user wants it saved before
answering them.
- Save plans as `docs/dev/plan_<feature-name>.md` (lowercase,
dash-separated, e.g. `plan_background-refactor.md`). Use the same
`<feature-name>` for the implementation branch
(`feature/<feature-name>`). Do not push the branch unless asked.
- Save plans as `docs/dev/plans/<feature-name>.md` (lowercase,
dash-separated, e.g. `docs/dev/plans/background-refactor.md`). When a
plan implements one ADR, use the same slug as the ADR file; for
example, `docs/dev/adrs/suggestions/foo.md` maps to
`docs/dev/plans/foo.md`. If a plan has no corresponding ADR or spans
multiple ADRs, choose a concise feature slug and list all related ADRs
in the plan. Use the same `<feature-name>` for the implementation
branch (`feature/<feature-name>`). Do not push the branch unless
asked.
- Include a status checklist with `[ ]` items; mark `[x]` as completed
during implementation.
- Apply the two-phase workflow (Phase 1 implementation, Phase 2
Expand All @@ -185,6 +210,12 @@ When asked to create a plan:
files likely to change, decisions already made, open questions,
verification commands for Phase 2, and a short suggested commit
message or branch name when useful.
- Verification commands in plans must include the zsh-safe log-capture
pattern from **Workflow** whenever saved output is needed for later
analysis.
- Before saving a plan, verify that referenced files, directories,
scripts, and task names exist locally when that is practical. If a
referenced tool is optional or missing, include an available fallback.
- End every plan with a "Suggested Pull Request" section containing a
short PR title and a brief end-user-oriented description. Keep this
section non-technical enough for scientists and other users to
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ on:
push:
branches:
- develop
# Do not run on version tags (those are handled by other workflows)
tags-ignore: ['v*']
# Trigger the workflow on pull request
pull_request:
# Allows you to run this workflow manually from the Actions tab
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/dashboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ jobs:
- name: Set up pixi
uses: ./.github/actions/setup-pixi

# Install badgery into the active Pixi environment without modifying
# pixi.toml/pixi.lock. Using `pixi add` here re-solves the whole project
# and rebuilds the local editable package, which can cause intermittent
# Linux CI failures (`Text file busy`, os error 26).
- name: Install badgery
shell: bash
run: pixi add --pypi --git https://github.com/enhantica/badgery badgery
run: pixi run python -m pip install git+https://github.com/enhantica/badgery

- name: Run docstring coverage and code complexity/maintainability checks
run: |
Expand Down
16 changes: 10 additions & 6 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Allow only one concurrent deployment to gh-pages at a time.
# All docs workflows share the same concurrency group to prevent race conditions
# when multiple branches/tags trigger simultaneous deployments.
# - Non-tagged pushes and pull requests all use `docs-dev` group, so
# they cancel each other.
# - Tagged pushes use their own group like docs-v1.2.3, so they do not
# cancel non-tagged runs, and non-tagged runs do not cancel them.
concurrency:
group: docs-gh-pages-deploy
cancel-in-progress: false
group: >-
${{ startsWith(github.ref, 'refs/tags/v')
&& format('docs-{0}', github.ref_name)
|| 'docs-dev' }}
cancel-in-progress: true

# Set the environment variables to be used in all jobs defined in this workflow
env:
Expand Down Expand Up @@ -115,7 +119,7 @@ jobs:
# Uses multiple cores for parallel execution to speed up the process.
- name: Run notebooks
# if: false # Temporarily disabled to speed up the docs build
run: pixi run notebook-exec
run: pixi run notebook-exec-ci

# Build the static files for the documentation site for local inspection
# Input: docs/ directory containing the Markdown files
Expand Down
49 changes: 19 additions & 30 deletions .github/workflows/issues-labels.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Verifies if an issue has at least one of the `[scope]` and one of the
# `[priority]` labels. If not, the bot adds labels with a warning emoji
# to indicate that those labels need to be added.
# Verifies if the current issue has at least one `[scope]` label and one
# `[priority]` label. If either is missing, the workflow adds a reminder label.

name: Issue labels check

Expand All @@ -13,39 +12,29 @@ permissions:

jobs:
check-labels:
if: github.actor != 'easyscience[bot]'

runs-on: ubuntu-latest

concurrency:
group: issue-labels-${{ github.event.issue.number }}
cancel-in-progress: true

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Setup easyscience[bot]
id: bot
uses: ./.github/actions/setup-easyscience-bot
- name: Ensure [scope] label
uses: Rindrics/expect-label-prefix@v1.2.1
with:
app-id: ${{ vars.EASYSCIENCE_APP_ID }}
private-key: ${{ secrets.EASYSCIENCE_APP_KEY }}

- name: Check for required [scope] label
uses: trstringer/require-label-prefix@v1
with:
secret: ${{ steps.bot.outputs.token }}
prefix: '[scope]'
labelSeparator: ' '
addLabel: true
defaultLabel: '[scope] ⚠️ label needed'

- name: Check for required [priority] label
uses: trstringer/require-label-prefix@v1
repository_full_name: ${{ github.repository }}
token: ${{ github.token }}
label_prefix: '[scope]'
label_separator: ' '
add_label: 'true'
default_label: '[scope] ⚠️ label needed'

- name: Ensure [priority] label
uses: Rindrics/expect-label-prefix@v1.2.1
with:
secret: ${{ steps.bot.outputs.token }}
prefix: '[priority]'
labelSeparator: ' '
addLabel: true
defaultLabel: '[priority] ⚠️ label needed'
repository_full_name: ${{ github.repository }}
token: ${{ github.token }}
label_prefix: '[priority]'
label_separator: ' '
add_label: 'true'
default_label: '[priority] ⚠️ label needed'
67 changes: 28 additions & 39 deletions .github/workflows/pr-labels.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
# Verifies if a pull request has at least one label from a set of valid
# labels before it can be merged.
#
# NOTE:
# This workflow may be triggered twice in quick succession when a PR is
# created:
# 1) `opened` — when the pull request is initially created
# 2) `labeled` — if labels are added immediately after creation
# (e.g. by manual labeling, another workflow, or GitHub App).
#
# These are separate GitHub events, so two workflow runs can be started.
# The label validation is delegated to `mheap/github-action-required-labels`,
# which checks the current PR labels via the GitHub API and can add or update a
# PR comment when the required label set is missing.

name: PR labels check

Expand All @@ -17,40 +12,34 @@ on:
types: [opened, labeled, unlabeled, synchronize]

permissions:
pull-requests: read
issues: write
pull-requests: write

jobs:
check-labels:
runs-on: ubuntu-latest

steps:
- name: Check for valid labels
run: |
PR_LABELS=$(echo '${{ toJson(github.event.pull_request.labels.*.name) }}' | jq -r '.[]')

echo "Current PR labels: $PR_LABELS"
VALID_LABELS=(
"[bot] release"
"[scope] bug"
"[scope] documentation"
"[scope] enhancement"
"[scope] maintenance"
"[scope] significant"
)

found=false
for label in "${VALID_LABELS[@]}"; do
if echo "$PR_LABELS" | grep -Fxq "$label"; then
echo "✅ Found valid label: $label"
found=true
break
fi
done

if [ "$found" = false ]; then
echo "ERROR: PR must have at least one of the following labels:"
for label in "${VALID_LABELS[@]}"; do
echo " - $label"
done
exit 1
fi
- name: Checkout repository
uses: actions/checkout@v6

- name: Setup easyscience[bot]
id: bot
uses: ./.github/actions/setup-easyscience-bot
with:
app-id: ${{ vars.EASYSCIENCE_APP_ID }}
private-key: ${{ secrets.EASYSCIENCE_APP_KEY }}

- uses: mheap/github-action-required-labels@v5
with:
token: ${{ steps.bot.outputs.token }}
add_comment: true
mode: minimum
count: 1
labels: |
[bot] release
[scope] bug
[scope] documentation
[scope] enhancement
[scope] maintenance
[scope] significant
2 changes: 1 addition & 1 deletion .github/workflows/release-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
gh pr create \
--base ${{ env.DEFAULT_BRANCH }} \
--head ${{ env.SOURCE_BRANCH }} \
--title "Release: merge ${{ env.SOURCE_BRANCH }} into ${{ env.DEFAULT_BRANCH }}" \
--title "🎉 Release: merge ${{ env.SOURCE_BRANCH }} into ${{ env.DEFAULT_BRANCH }}" \
--label "[bot] release" \
--body "This PR is created automatically to trigger the release pipeline. It merges the accumulated changes from \`${{ env.SOURCE_BRANCH }}\` into \`${{ env.DEFAULT_BRANCH }}\`.

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,10 @@ jobs:
exit 1
fi

whl_url="file://$(python -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "${whl_path[0]}")"
whl_abs_path="$(python -c 'import os,sys; print(os.path.abspath(sys.argv[1]))' "${whl_path[0]}")"

echo "Adding easydiffraction from: $whl_url"
pixi add --pypi "easydiffraction[dev] @ ${whl_url}"
echo "Adding easydiffraction from: $whl_abs_path"
pixi add --pypi "easydiffraction[dev] @ ${whl_abs_path}"

echo "Exiting pixi project directory"
cd ..
Expand Down
Loading
Loading