diff --git a/.github/REUSABLE_WORKFLOWS.md b/.github/REUSABLE_WORKFLOWS.md index 00b9068dc..a8306a1ce 100644 --- a/.github/REUSABLE_WORKFLOWS.md +++ b/.github/REUSABLE_WORKFLOWS.md @@ -5,7 +5,7 @@ The workflows in `Framework-R-D/phlex/` may be invoked as follows: 1. Automatically as part of CI checks on a PR submitted to `Framework-R-D/phlex`, at PR creation time and thereafter on pushes to the PR branch. This should work whether your PR branch is situated in the primary repository or a fork. -1. Via triggering comments on the PR (`@${{ github.event.repository.name }}bot `). +1. Via triggering comments on the PR (`@phlexbot ` for this repository; on a fork named `my-phlex`, the bot name is `@my-phlexbot`). 1. Via the "actions" tab on the project's GitHub web page. Additionally, you can configure your own fork of Phlex to run CI checks on local PRs, and on its default branch, following the instructions below. @@ -596,6 +596,75 @@ Centralized workflow that calls all format fix workflows in parallel and posts a **Note:** This workflow is not designed to be called via `workflow_call` from other repositories. It is specifically for use within the Phlex repository. +### 16. `clang-format-check.yaml` + +Checks C++ source files for formatting issues using `clang-format`. + +#### Usage Example + +```yaml +jobs: + check_clang_format: + uses: Framework-R-D/phlex/.github/workflows/clang-format-check.yaml@ +``` + +#### All Inputs + +- `checkout-path` (string, optional): Path to check out code to. +- `skip-relevance-check` (boolean, optional, default: `false`): Bypass the check that only runs if C++ files have changed. +- `ref` (string, optional): The branch, ref, or SHA to check out. +- `repo` (string, optional): The repository to check out from. +- `pr-base-sha` (string, optional): Base SHA of the PR for relevance check. +- `pr-head-sha` (string, optional): Head SHA of the PR for relevance check. + +### 17. `header-guards-check.yaml` + +Checks C++ header files for correct header guard formatting. + +#### Usage Example + +```yaml +jobs: + check_header_guards: + uses: Framework-R-D/phlex/.github/workflows/header-guards-check.yaml@ +``` + +#### All Inputs + +- `checkout-path` (string, optional): Path to check out code to. +- `skip-relevance-check` (boolean, optional, default: `false`): Bypass the check that only runs if C++ header files have changed. +- `ref` (string, optional): The branch, ref, or SHA to check out. +- `repo` (string, optional): The repository to check out from. +- `pr-base-sha` (string, optional): Base SHA of the PR for relevance check. +- `pr-head-sha` (string, optional): Head SHA of the PR for relevance check. + +### 18. `yaml-check.yaml` + +Checks YAML files for formatting and syntax issues using `yamllint`. + +#### Usage Example + +```yaml +jobs: + check_yaml: + uses: Framework-R-D/phlex/.github/workflows/yaml-check.yaml@ +``` + +#### All Inputs + +- `checkout-path` (string, optional): Path to check out code to. +- `skip-relevance-check` (boolean, optional, default: `false`): Bypass the check that only runs if YAML files have changed. +- `ref` (string, optional): The branch, ref, or SHA to check out. +- `repo` (string, optional): The repository to check out from. +- `pr-base-sha` (string, optional): Base SHA of the PR for relevance check. +- `pr-head-sha` (string, optional): Head SHA of the PR for relevance check. + ### Other Workflows -The repository also provides `clang-tidy-check.yaml` and `clang-tidy-fix.yaml`. These workflows are currently **not** available for reuse via `workflow_call` as they are specifically intended for use on this repository and its forks. +The following workflows exist in the repository but are **not** designed for reuse via `workflow_call`: + +- `clang-tidy-check.yaml` — runs clang-tidy analysis; only for use within this repository and its forks +- `clang-tidy-fix.yaml` — applies clang-tidy fixes; only for use within this repository and its forks +- `clang-tidy-report.yaml` — posts clang-tidy PR comments via `workflow_run`; internal companion to `clang-tidy-check.yaml` +- `codeql-analysis.yaml` (when called from outside; see §11 for supported `workflow_call` usage) — the companion `codeql-comment.yaml` is internal +- `add-issues.yaml`, `coverage.yaml`, `dependabot-auto-merge.yaml` — repository-specific internal workflows diff --git a/.github/actions/handle-fix-commit/action.yaml b/.github/actions/handle-fix-commit/action.yaml index 8b1ba2386..2305a84cd 100644 --- a/.github/actions/handle-fix-commit/action.yaml +++ b/.github/actions/handle-fix-commit/action.yaml @@ -162,7 +162,7 @@ runs: - name: Upload patch if: steps.create_patch.outputs.patch_name - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: fix-patch path: ${{ inputs.working-directory }}/${{ steps.create_patch.outputs.patch_name }} diff --git a/.github/actions/post-clang-tidy-results/action.yaml b/.github/actions/post-clang-tidy-results/action.yaml index f8a727e69..b60e389df 100644 --- a/.github/actions/post-clang-tidy-results/action.yaml +++ b/.github/actions/post-clang-tidy-results/action.yaml @@ -21,7 +21,7 @@ runs: using: "composite" steps: - name: Download artifacts - uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: pattern: clang-tidy-* merge-multiple: true @@ -112,7 +112,7 @@ runs: body += '\n'; } - body += 'See inline comments for details. Comment `@phlexbot tidy-fix` to auto-fix.'; + body += `See inline comments for details. Comment \`@${context.repo.repo}bot tidy-fix\` to auto-fix.`; await github.rest.issues.createComment({ owner: context.repo.owner, diff --git a/.github/workflows/clang-format-check.yaml b/.github/workflows/clang-format-check.yaml index 23c4bdc15..0e3e2193b 100644 --- a/.github/workflows/clang-format-check.yaml +++ b/.github/workflows/clang-format-check.yaml @@ -15,6 +15,33 @@ permissions: description: "The branch, ref, or SHA to checkout. Defaults to the repository's default branch." required: false type: string + workflow_call: + inputs: + checkout-path: + description: "Path to check out code to" + required: false + type: string + skip-relevance-check: + description: "Bypass relevance check" + required: false + type: boolean + default: false + pr-base-sha: + description: "Base SHA of the PR for relevance check" + required: false + type: string + pr-head-sha: + description: "Head SHA of the PR for relevance check" + required: false + type: string + ref: + description: "The branch, ref, or SHA to checkout" + required: false + type: string + repo: + description: "The repository to checkout from" + required: false + type: string jobs: setup: @@ -33,11 +60,20 @@ jobs: uses: Framework-R-D/phlex/.github/actions/workflow-setup@main with: file-type: cpp + head-ref: ${{ inputs.pr-head-sha }} + ref: ${{ inputs.ref }} + repo: ${{ inputs.repo }} + pr-base-sha: ${{ inputs.pr-base-sha }} + checkout-path: ${{ inputs.checkout-path }} clang-format-check: needs: setup if: > - always() && (github.event_name == 'workflow_dispatch' || needs.setup.outputs.has_changes == 'true') + always() && ( + github.event_name == 'workflow_dispatch' || + inputs.skip-relevance-check || + needs.setup.outputs.has_changes == 'true' + ) runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/clang-tidy-check.yaml b/.github/workflows/clang-tidy-check.yaml index 3d4fd0163..e478df347 100644 --- a/.github/workflows/clang-tidy-check.yaml +++ b/.github/workflows/clang-tidy-check.yaml @@ -27,7 +27,7 @@ jobs: github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(fromJSON('["OWNER", "COLLABORATOR", "MEMBER"]'), github.event.comment.author_association) && - startsWith(github.event.comment.body, '@phlexbot tidy-check') + startsWith(github.event.comment.body, format('@{0}bot tidy-check', github.event.repository.name)) ) outputs: is_act: ${{ steps.setup.outputs.is_act }} diff --git a/.github/workflows/yaml-check.yaml b/.github/workflows/yaml-check.yaml index 31ea03e90..8cfe95928 100644 --- a/.github/workflows/yaml-check.yaml +++ b/.github/workflows/yaml-check.yaml @@ -3,6 +3,7 @@ name: YAML Check permissions: contents: read + pull-requests: read "on": pull_request: @@ -14,6 +15,33 @@ permissions: description: "The branch, ref, or SHA to checkout. Defaults to the repository's default branch." required: false type: string + workflow_call: + inputs: + checkout-path: + description: "Path to check out code to" + required: false + type: string + skip-relevance-check: + description: "Bypass relevance check" + required: false + type: boolean + default: false + pr-base-sha: + description: "Base SHA of the PR for relevance check" + required: false + type: string + pr-head-sha: + description: "Head SHA of the PR for relevance check" + required: false + type: string + ref: + description: "The branch, ref, or SHA to checkout" + required: false + type: string + repo: + description: "The repository to checkout from" + required: false + type: string jobs: setup: @@ -32,11 +60,17 @@ jobs: uses: Framework-R-D/phlex/.github/actions/workflow-setup@main with: file-type: yaml + head-ref: ${{ inputs.pr-head-sha }} + ref: ${{ inputs.ref }} + repo: ${{ inputs.repo }} + pr-base-sha: ${{ inputs.pr-base-sha }} + checkout-path: ${{ inputs.checkout-path }} yaml-check: needs: setup if: > - always() && (github.event_name == 'workflow_dispatch' || needs.setup.outputs.has_changes == 'true') + always() && (github.event_name == 'workflow_dispatch' || inputs.skip-relevance-check || + needs.setup.outputs.has_changes == 'true') runs-on: ubuntu-latest steps: - name: Checkout code @@ -47,13 +81,11 @@ jobs: repository: ${{ needs.setup.outputs.repo }} persist-credentials: false - - name: Setup Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: "3.x" + - name: Install uv + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 - name: Install yamllint - run: pip install yamllint + run: uv tool install yamllint - name: Run yamllint id: lint diff --git a/CLANG_TIDY_CONFIGURATION.md b/CLANG_TIDY_CONFIGURATION.md index d0ab72556..b5040b5f6 100644 --- a/CLANG_TIDY_CONFIGURATION.md +++ b/CLANG_TIDY_CONFIGURATION.md @@ -103,28 +103,54 @@ The configuration enforces consistent naming: **Purpose:** Automatically check C++ code for Core Guidelines compliance on pull requests +**Triggers:** `pull_request`, `push` to `release/*` branches, `issue_comment` (`@phlexbot tidy-check`), `workflow_dispatch` + **Features:** -- Runs on PR to main branch and manual trigger +- Runs on every PR and release-branch push, on manual trigger, and on `@phlexbot tidy-check` comment - Configures project with the `clang-tidy` CMake preset (enables compile commands export and disables C++ module scanning) - Runs `run-clang-tidy` over selected source trees (`phlex`, `form`, `plugins`, `test`) - Reports warnings and errors with detailed output -- Uploads clang-tidy fixes YAML and log as artifacts -- Posts inline PR comments for detected issues +- Uploads clang-tidy fixes YAML, log, and PR number as artifacts (retention: 7 days) +- For `issue_comment` and `workflow_dispatch` events, posts inline PR comments directly +- For `pull_request` events, defers comment posting to `clang-tidy-report.yaml` (see below) **How it works:** 1. Configure the project with the `clang-tidy` CMake preset (implies `CMAKE_EXPORT_COMPILE_COMMANDS=YES` and `CMAKE_CXX_SCAN_FOR_MODULES=OFF`) 2. Run `run-clang-tidy -p -export-fixes /clang-tidy-fixes.yaml -j ` from the source root 3. Restrict path arguments to source directories so generated build files are excluded -4. Parse output, upload artifacts, and post inline PR comments +4. On `pull_request` events, save `pr_number.txt` alongside the fix artifacts +5. Upload artifacts; `clang-tidy-report.yaml` picks them up for fork-safe PR commenting **How to use:** - Automatically runs on every pull request -- Review the workflow output and inline PR comments for details +- Review inline PR comments for details (posted by `clang-tidy-report.yaml` for PR events) - Comment `@phlexbot tidy-fix` to attempt automatic fixes +### Clang-Tidy Report (`clang-tidy-report.yaml`) + +**Purpose:** Post clang-tidy results as PR comments for pull requests, including those from fork repositories + +**Trigger:** `workflow_run` on completion of the "Clang-Tidy Check" workflow + +**Why a separate workflow?** + +For pull requests from forked repositories, GitHub caps the `GITHUB_TOKEN` at read-only +access during `pull_request` events, regardless of the `permissions:` block in the YAML. +Posting PR comments (a write operation) therefore cannot be done inside `clang-tidy-check.yaml` +for fork PRs. The `workflow_run` event always runs in the base repository's context and can +be granted write access, so `clang-tidy-report.yaml` handles all PR comment posting for +`pull_request`-triggered runs. + +**How it works:** + +1. Triggered after every "Clang-Tidy Check" run that was itself triggered by a `pull_request` event +2. Downloads the `clang-tidy-check` artifact bundle (which includes `pr_number.txt`, `clang-tidy-fixes.yaml`, and `clang-tidy-new-issues.txt`) using the originating `run-id` for cross-run artifact access +3. Extracts the PR number from `pr_number.txt` +4. Calls the `post-clang-tidy-results` action to post inline comments and a summary + ### Clang-Tidy Fix (`clang-tidy-fix.yaml`) **Purpose:** Automatically apply clang-tidy fixes when triggered by comment diff --git a/DEVELOPING.md b/DEVELOPING.md index fb3d5c5b2..1bf68e243 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -105,7 +105,7 @@ The upload command uses the Codecov CLI and automatically normalizes paths for r ## Coverage in CI -The project automatically runs coverage analysis on every PR and push to main/develop branches. The workflow: +The project automatically runs coverage analysis on every PR and push to the `main` and `release/*` branches. The workflow: 1. Builds with `-DCMAKE_BUILD_TYPE=Coverage -DENABLE_COVERAGE=ON` 2. Runs all tests via `ctest` @@ -131,9 +131,11 @@ If you wish to add your own personalized instructions, or adjust/augment the rep The tool pre-commit offers a framework for setting up hooks that are run on staged files before committing, ensuring correct formatting and catching some errors before they end up in a commit. -To set up this tool locally, first install `pre-commit` (or `prek`, a faster re-implementation in rust) using your system package manager or `uv`/`pip(x)`, e.g. `uv tool install pre-commit`. +In the devcontainer, `prek` (a faster Rust re-implementation of `pre-commit`) is already installed and the hooks are configured automatically. No manual setup is needed in that environment. -So set up the hooks in the Phlex repository, run the `pre-commit install` command once in the repository. The hooks now should run automatically prior to each commit. +Outside the devcontainer, install `pre-commit` or `prek` using your system package manager or `uv`/`pip(x)`, e.g. `uv tool install pre-commit`. + +To set up the hooks in the Phlex repository, run the `pre-commit install` command once in the repository. The hooks now should run automatically prior to each commit. To skip a check temporarily, run `SKIP=ruff-format git commit -m "..."`. To skip all hooks, you can use the `--no-verify` flag to `git commit`.