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
53 changes: 53 additions & 0 deletions .github/workflows/check-dependency-graph.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Check Dependency Graph (reusable)

on:
workflow_call:
inputs:
script-dir:
description: >-
Directory holding the vendored `build_dependency_graph.py`, with its
self-test under `tests/`.
type: string
default: tools
pages-dir:
description: >-
Directory under the repository root holding the pages (`.` when
pages sit at the root).
type: string
default: chapters
site:
description: >-
This site's name in cross-site node keys (default: the repository
name).
type: string
default: ''
fail-on-cycle:
description: Fail the job when the graph has a cycle (else warn only).
type: boolean
default: true

jobs:
check-dependency-graph:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Run the builder's self-test
env:
DG_SCRIPT_DIR: ${{ inputs.script-dir }}
run: python3 "$DG_SCRIPT_DIR/tests/test_build_dependency_graph.py"

- name: Build the graph
env:
DG_SCRIPT_DIR: ${{ inputs.script-dir }}
DG_PAGES: ${{ inputs.pages-dir }}
DG_SITE: ${{ inputs.site || github.event.repository.name }}
DG_FAIL: ${{ inputs.fail-on-cycle }}
run: |
args=(--pages "$DG_PAGES" --site "$DG_SITE" --out "${RUNNER_TEMP}/dependency-graph.json")
if [ "$DG_FAIL" = "true" ]; then args+=(--fail); fi
python3 "$DG_SCRIPT_DIR/build_dependency_graph.py" "${args[@]}"
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ while `opposition-research`, `check-dependency-updates`,
`check-source-overlap`,
`check-quarto-prose`, `check-orphaned-images`, `check-r-package`,
`check-python-package`, `check-typed-output`,
`check-informal-definitions`, `check-literal-math-letters`, `check-wikipedia-further-reading`, `check-redundant-citations`, `check-one-div-per-subfile`, `check-term-links`, `check-paired-file-change`, `annotation-gate`, `annotation-gate-run`, `check-local-macros`, `check-fform-paren`, `check-write-idiom`, `cleanup-pr-previews`, `student-qmd`,
`check-informal-definitions`, `check-literal-math-letters`, `check-wikipedia-further-reading`, `check-redundant-citations`, `check-one-div-per-subfile`, `check-term-links`, `check-dependency-graph`, `check-paired-file-change`, `annotation-gate`, `annotation-gate-run`, `check-local-macros`, `check-fform-paren`, `check-write-idiom`, `cleanup-pr-previews`, `student-qmd`,
`update-quarto-extensions`, and `update-snapshots`
only ever shipped at `@v3` (or moved to `@v3` for `cleanup-pr-previews` and `update-snapshots`).

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ not reference `@main` from consumers.
| `annotation-gate.yml` | Fail the run when any other job carries a notice, warning or failure annotation not on an allowlist, so an annotation cannot sit on a green job | `levels`, `allow-patterns`, `job-name` |
| `annotation-gate-run.yml` | Gate a finished run from a `workflow_run` workflow and post the result as an `annotation-gate` check run, for repositories whose checks are spread over many workflow files | `run-id`, `head-sha`, `run-attempt`, `levels`, `allow-patterns` |
| `check-fform-paren.yml` | Diff-scoped, warn-only check that flags `\name\paren{...}` (or `\sb{`, `\cb{`) where an f form `\namef{...}` is defined in the macros file (default `latex-macros/macros.qmd`) | `macros-file`, `globs`, `paths-ignore`, `submodules`, `fail`, `whole-tree` |
| `check-dependency-graph.yml` | Run the self-test of a notes repo's vendored `build_dependency_graph.py`, then build its definition and result graph and fail on a cycle | `script-dir`, `pages-dir`, `site`, `fail-on-cycle` |
| `check-write-idiom.yml` | Diff-scoped, warn-only check that flags a line opening with `Write the`, `Write a` or `Write an` (after an optional list marker and label), because "Write ..." hides whether to derive, express, state or give | `globs`, `paths-ignore`, `fail`, `whole-tree` |
| `lint-qmd.yml` | markdownlint over the prose sections of tracked `.qmd` Quarto files (code chunks stripped, YAML front matter skipped natively) with a bundled default config; default 80-char line-length ceiling encourages semantic line breaks | `config-file`, `globs`, `paths-ignore`, `fail`, `max-line-length` |
| `lint-changed-lines.yml` | lintr over only the lines a PR adds or modifies (not whole changed files), so lint rules can be adopted or tightened incrementally | `path`, `install-quarto`, `use-renv`, `renv-cache-version`, `apt-packages`, `extra-packages`, `install-package`, `fail` |
Expand Down Expand Up @@ -137,7 +138,7 @@ that need to write must have the **caller** grant it on the calling job:
`models: read`, `contents: read`.

- <!--readonly-workflows:begin-->`annotation-gate`, `check-ai-tells`, `check-bibliography-dois`,
`check-code-similarity`, `check-duplicate-roxygen`, `check-equation-renders`, `check-extra`,
`check-code-similarity`, `check-dependency-graph`, `check-duplicate-roxygen`, `check-equation-renders`, `check-extra`,
`check-formatting`, `check-informal-definitions`, `check-junk-files`, `check-literal-math-letters`, `check-wikipedia-further-reading`, `check-redundant-citations`, `check-one-div-per-subfile`, `check-term-links`, `check-paired-file-change`, `check-local-macros`, `check-fform-paren`, `check-write-idiom`, `check-math-definitions`,
`check-merge-drops`,
`check-new-line-breaks`, `check-news`,
Expand Down Expand Up @@ -683,7 +684,7 @@ Pin
`check-one-function-per-file.yml`
only ever shipped at `@v2` (too new to exist at the frozen `@v1` tag).
`check-dependency-updates.yml`, `check-duplicate-roxygen.yml`,
`check-informal-definitions.yml`, `check-literal-math-letters.yml`, `check-wikipedia-further-reading.yml`, `check-redundant-citations.yml`, `check-one-div-per-subfile.yml`, `check-term-links.yml`, `check-paired-file-change.yml`, `annotation-gate.yml`, `annotation-gate-run.yml`, `check-local-macros.yml`, `check-fform-paren.yml`, `check-write-idiom.yml`,
`check-informal-definitions.yml`, `check-literal-math-letters.yml`, `check-wikipedia-further-reading.yml`, `check-redundant-citations.yml`, `check-one-div-per-subfile.yml`, `check-term-links.yml`, `check-paired-file-change.yml`, `annotation-gate.yml`, `annotation-gate-run.yml`, `check-local-macros.yml`, `check-fform-paren.yml`, `check-dependency-graph.yml`, `check-write-idiom.yml`,
`check-math-definitions.yml`,
`check-merge-drops.yml`, `check-orphaned-images.yml`,
`check-python-package.yml`, `check-quarto-book.yml`,
Expand Down Expand Up @@ -831,7 +832,7 @@ templates intentionally track the moving major tag (currently `@v1`, except
`check-code-similarity.yml`, and
`check-one-function-per-file.yml` at `@v2`, and
`check-dependency-updates.yml`, `check-duplicate-roxygen.yml`,
`check-informal-definitions.yml`, `check-literal-math-letters.yml`, `check-wikipedia-further-reading.yml`, `check-redundant-citations.yml`, `check-one-div-per-subfile.yml`, `check-term-links.yml`, `check-paired-file-change.yml`, `annotation-gate.yml`, `annotation-gate-run.yml`, `check-local-macros.yml`, `check-fform-paren.yml`, `check-write-idiom.yml`,
`check-informal-definitions.yml`, `check-literal-math-letters.yml`, `check-wikipedia-further-reading.yml`, `check-redundant-citations.yml`, `check-one-div-per-subfile.yml`, `check-term-links.yml`, `check-paired-file-change.yml`, `annotation-gate.yml`, `annotation-gate-run.yml`, `check-local-macros.yml`, `check-fform-paren.yml`, `check-dependency-graph.yml`, `check-write-idiom.yml`,
`check-math-definitions.yml`,
`check-merge-drops.yml`, `check-orphaned-images.yml`,
`check-python-package.yml`, `check-quarto-book.yml`,
Expand Down
5 changes: 5 additions & 0 deletions changelog.d/check-dependency-graph.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- **New `check-dependency-graph.yml` reusable workflow**
([#1129](https://github.com/Morrison-Lab/gha/issues/1129)).
It runs the self-test of a repository's vendored `build_dependency_graph.py`.
It then builds the graph and fails on a cycle.
Notes repos that vendor the script from `build-dependency-graph` call it in place of a per-repo workflow.
21 changes: 21 additions & 0 deletions examples/check-dependency-graph.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copy to .github/workflows/check-dependency-graph.yml in your repo.
name: Check Dependency Graph

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
check:
uses: Morrison-Lab/gha/.github/workflows/check-dependency-graph.yml@v3
# with:
# # Pages at the repository root instead of chapters/.
# pages-dir: .
# # Where the vendored script and its tests live.
# script-dir: tools
# # Warn instead of failing on a cycle.
# fail-on-cycle: false
1 change: 1 addition & 0 deletions website/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ website:
- reference/check-duplicate-roxygen.qmd
- reference/check-formatting.qmd
- reference/check-junk-files.qmd
- reference/check-dependency-graph.qmd
- reference/check-math-definitions.qmd
- reference/check-merge-drops.qmd
- reference/check-non-standard-chars.qmd
Expand Down
2 changes: 1 addition & 1 deletion website/permissions.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ already include the right `permissions:` blocks; copy them as-is.
## Per-workflow grants

- <!--readonly-workflows:begin-->`annotation-gate`, `check-ai-tells`, `check-bibliography-dois`,
`check-code-similarity`, `check-duplicate-roxygen`,
`check-code-similarity`, `check-dependency-graph`, `check-duplicate-roxygen`,
`check-equation-renders`, `check-extra`,
`check-formatting`, `check-informal-definitions`, `check-junk-files`,
`check-literal-math-letters`, `check-wikipedia-further-reading`, `check-redundant-citations`,
Expand Down
56 changes: 56 additions & 0 deletions website/reference/check-dependency-graph.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: "check-dependency-graph.yml"
---

Run the self-test of a notes repository's vendored
`build_dependency_graph.py`,
then build the graph of its definition and result divs and fail on a cycle.

The script comes from the `build-dependency-graph` action.
Notes repositories vendor it under `tools/`
so that a local render can run it as a `pre-render` step.
Nothing else runs the vendored copy's self-test,
so a change to the script in one repository
can break it without any check going red.

## What it does

1. Runs `<script-dir>/tests/test_build_dependency_graph.py`.
2. Runs `<script-dir>/build_dependency_graph.py` on the pages,
writing the JSON to the runner's temporary directory.
With `fail-on-cycle` it exits non-zero
when a definition or result div
depends on itself through other divs.

Forward references are printed and never fail the job.

## Inputs

| Input | Type | Default | Description |
| --------------- | ------- | ------- | ----------- |
| `script-dir` | string | `tools` | Directory holding the vendored script, with its self-test under `tests/`. |
| `pages-dir` | string | `chapters` | Directory under the repository root holding the pages (`.` when pages sit at the root). |
| `site` | string | the repository name | This site's name in cross-site node keys. |
| `fail-on-cycle` | boolean | `true` | Fail the job when the graph has a cycle (else warn only). |

## Permissions

Only `contents: read` (the default), so no `permissions:` block is needed.

## Example

```yaml
name: Check dependency graph
on:
push: { branches: [main] }
pull_request:
jobs:
check:
uses: Morrison-Lab/gha/.github/workflows/check-dependency-graph.yml@v3
# with:
# pages-dir: .
```

See `check-dependency-graph.yml` in
[`examples/`](https://github.com/Morrison-Lab/gha/tree/main/examples)
for the full caller stub.
2 changes: 2 additions & 0 deletions website/versioning.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ only ever shipped at
`annotation-gate.yml`,
`annotation-gate-run.yml`,
`check-local-macros.yml`, `check-fform-paren.yml`, `check-write-idiom.yml`,
`check-dependency-graph.yml`,
`check-math-definitions.yml`,
`check-merge-drops.yml`, `check-orphaned-images.yml`,
`check-python-package.yml`, `check-quarto-book.yml`,
Expand Down Expand Up @@ -183,6 +184,7 @@ intentionally track the moving major tag (currently `@v1`, except `preview.yml`,
`annotation-gate.yml`,
`annotation-gate-run.yml`,
`check-local-macros.yml`, `check-fform-paren.yml`, `check-write-idiom.yml`,
`check-dependency-graph.yml`,
`check-math-definitions.yml`,
`check-merge-drops.yml`,
`check-repo-hygiene.yml`, `check-quarto-website.yml`,
Expand Down
2 changes: 2 additions & 0 deletions website/workflows.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ input tables and a copy-paste example.
| [`annotation-gate.yml`](reference/annotation-gate.qmd) | Fail the run when any other job carries a notice, warning or failure annotation not on an allowlist, so an annotation cannot sit on a green job | `levels`, `allow-patterns`, `job-name` |
| [`annotation-gate-run.yml`](reference/annotation-gate.qmd) | Gate a finished run from a `workflow_run` workflow and post the result as an `annotation-gate` check run, for repositories whose checks are spread over many workflow files | `run-id`, `head-sha`, `run-attempt`, `levels`, `allow-patterns` |
| [`check-fform-paren.yml`](reference/check-fform-paren.qmd) | Diff-scoped, warn-only check that flags `\name\paren{...}` (or `\sb{`, `\cb{`) where an f form `\namef{...}` is defined in the macros file (default `latex-macros/macros.qmd`) | `macros-file`, `globs`, `paths-ignore`, `submodules`, `fail`, `whole-tree` |
| [`check-dependency-graph.yml`](reference/check-dependency-graph.qmd) | Run the self-test of a notes repo's vendored `build_dependency_graph.py`, then build its definition and result graph and fail on a cycle | `script-dir`, `pages-dir`, `site`, `fail-on-cycle` |
| [`check-write-idiom.yml`](reference/check-write-idiom.qmd) | Diff-scoped, warn-only check that flags a line opening with `Write the`, `Write a` or `Write an` (after an optional list marker and label), because "Write ..." hides whether to derive, express, state or give | `globs`, `paths-ignore`, `fail`, `whole-tree` |
| [`lint-qmd.yml`](reference/lint-qmd.qmd) | markdownlint over the prose sections of tracked `.qmd` Quarto files (code chunks stripped, YAML front matter skipped natively) with a bundled default config; default 80-char line-length ceiling encourages semantic line breaks | `config-file`, `globs`, `paths-ignore`, `fail`, `max-line-length` |
| [`lint-changed-lines.yml`](reference/lint-changed-lines.qmd) | lintr over only the lines a PR adds or modifies (not whole changed files), so lint rules can be adopted or tightened incrementally | `path`, `install-quarto`, `use-renv`, `renv-cache-version`, `apt-packages`, `extra-packages`, `install-package`, `fail` |
Expand Down Expand Up @@ -120,6 +121,7 @@ only ever shipped at `@v2` (too new to exist at the frozen `@v1` tag).
`annotation-gate.yml`,
`annotation-gate-run.yml`,
`check-local-macros.yml`, `check-fform-paren.yml`, `check-write-idiom.yml`,
`check-dependency-graph.yml`,
`cleanup-pr-previews.yml`,
`opposition-research.yml`,
`student-qmd.yml`, `update-quarto-extensions.yml`, and
Expand Down
Loading