diff --git a/.github/CodeQL-README.md b/.github/CodeQL-README.md
index f3871f7d..cff74fd4 100644
--- a/.github/CodeQL-README.md
+++ b/.github/CodeQL-README.md
@@ -1,4 +1,3 @@
-```markdown
# CodeQL scanning for this repository
This repository uses C++ (C++20 / moving to C++23) built with CMake under the phlex-src directory, plus some Python and CI bits (Bash). The repository includes a CodeQL GitHub Actions workflow on branch `copilot/codeql-workflow` that:
@@ -9,44 +8,51 @@ This repository uses C++ (C++20 / moving to C++23) built with CMake under the ph
- Uses RelWithDebInfo build type in CI so debug symbols are present while keeping realistic optimization.
Important workflow-specific notes
+
- The workflow sets `autobuild: false` during the CodeQL init so the repository's own configure / build steps run. This is intentional: the Phlex build actions are used to build exactly what you ship.
- The workflow tries to locate and copy a compile_commands.json (from `phlex-src/build/` or `phlex-build/`) to the workspace root so diagnostic tools and manual inspection have a predictable path.
- The workflow runs inside the repository container image (if provided) so it uses the same toolchain and environment your CI expects.
How the workflow is targeted at phlex-src
+
- The CMake configure & build steps are run with `-S phlex-src -B phlex-src/build` (or your Phlex-specific helpers are invoked in that context) so compile units, compiler flags, and generated compile_commands reference files under `phlex-src`.
- The CodeQL config (`.github/codeql/codeql-config.yml`) contains an explicit `paths.include: - phlex-src/**` entry and excludes common vendor/build directories. This ensures CodeQL focuses on the intended code and not third-party or generated artifacts.
Recommended build type for CodeQL runs
+
- Use RelWithDebInfo (the workflow is already set to use this). Rationale:
- RelWithDebInfo produces debug symbols (required for better mapping of findings to source/stack traces) while compiling with optimizations closer to production.
- Pure Debug (-O0 -g) can be used for local triage of tricky alerts but is slower and sometimes produces analysis results that differ from optimized builds.
- Release (no debug info) is not recommended for CodeQL because missing debug symbols reduce the quality of evidence and traces in findings.
How to run CodeQL locally (examples)
-1. Install the CodeQL CLI: https://codeql.github.com/docs/codeql-cli/getting-started/
+
+1. Install the CodeQL CLI:
2. Create a C++ database for the phlex-src tree (example):
- From repository root:
codeql database create codeql-db --language=cpp --command="cmake -S phlex-src -B phlex-src/build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && cmake --build phlex-src/build -- -j$(nproc)"
3. Analyze the database:
- codeql database analyze codeql-db --format=sarifv2 --output=results-cpp.sarif github/codeql/cpp-security-and-quality
4. Python example (if you need to build a Python DB):
- - codeql database create codeql-python-db --language=python --command="python3 -m pip install -r phlex-src/requirements.txt"
+ - codeql database create codeql-python-db --language=python --command="python3 -m pip install -r phlex-src/requirements.txt"
- codeql database analyze codeql-python-db --format=sarifv2 --output=results-py.sarif github/codeql/python-security-and-quality
5. Open the SARIF in VS Code via the CodeQL extension or upload results via the GitHub UI.
Triage tips and workflows
+
- Start with high-confidence, high-severity alerts.
- Use the evidence shown in the CodeQL alert to locate the vulnerable trace. RelWithDebInfo gives better evidence than Release.
- When marking false positives, add a short rationale in the Code Scanning UI (this helps future auditors).
- If the repo has many historical findings, consider a triage sprint to baseline or create a SARIF baseline to ignore existing alerts temporarily while blocking new ones.
How to add or change query packs
+
- The repository currently selects the language security-and-quality packs for C++ and Python. That is a good default.
- If you want to add additional packs (experimental or specialized) you can:
- Edit `.github/codeql/codeql-config.yml` and add additional packs there (use the canonical pack name), or
- Add them to the init step in the workflow (`with: queries:`).
- Example of adding packs in the workflow init:
+
```yaml
uses: github/codeql-action/init@v4
with:
@@ -59,12 +65,14 @@ How to add or change query packs
```
Action-specific / workflow scanning
+
- There are CodeQL query packs that specifically analyze GitHub Actions workflow files (YAML) to find insecure patterns (for example: unsafe use of secrets, untrusted inputs in workflow run steps, usage of unpinned actions, etc.). If you rely on custom workflows or pass secrets/inputs to actions, consider enabling the GitHub Actions query pack if it is available in your CodeQL pack index.
- To discover whether an official GitHub Actions pack exists or to find its exact name, see the CodeQL packs index (the canonical source) or search the public CodeQL repository:
- - https://github.com/github/codeql/tree/main/packs
+ -
- Search for "github-actions" or "actions" in the CodeQL repo to find action-related packs and their exact pack names.
Recommended query packs for this repository (starting point)
+
- github/codeql/cpp-security-and-quality
- Purpose: Core security and quality queries for C and C++ codebases. Good coverage of common memory safety, API misuse, and typical C/C++ pitfalls.
- Why: Phlex is primarily C++, so this pack is the most important starting point.
@@ -73,6 +81,7 @@ Recommended query packs for this repository (starting point)
- Why: Phlex contains some Python; include this pack so those files are analyzed.
Other useful pack categories to consider
+
- Language experimental packs (e.g., "cpp-experimental" / "python-experimental")
- These provide newer/experimental queries that are not yet in the stable security-and-quality pack. Use cautiously: they can produce more findings and more false positives.
- Action/workflow packs (GitHub Actions specific)
@@ -81,15 +90,17 @@ Other useful pack categories to consider
- If Phlex heavily uses a certain third-party library that has its own pack, consider enabling it to get library-specific rules.
How to find the exact pack names and descriptions
+
- Official source: the GitHub CodeQL packs and QL repos:
- - https://github.com/github/codeql/tree/main/packs
- - https://github.com/github/codeql/tree/main/ql
+ -
+ -
- CodeQL CLI (partial support for pack discovery):
- You can use `codeql pack` and `codeql resolve` commands to inspect installed packs. The CodeQL CLI documentation shows usage for installing and listing packs.
- GitHub docs:
- Code scanning docs and the CodeQL repo README often list recommended packs and query categories.
Suggested immediate next steps
+
1. Keep the current packs (cpp-security-and-quality and python-security-and-quality) enabled in `.github/codeql/codeql-config.yml` — they are the right baseline.
2. Search the CodeQL packs index for any GitHub Actions pack and enable it if you want workflow-level checks.
3. If you want more thorough coverage, enable the experimental packs temporarily in a non-blocking run, review the alerts, then decide whether to include them in CI permanently.
@@ -125,4 +136,3 @@ When a PR is opened from a fork, the `GITHUB_TOKEN` does not have permission to
## Contact / Ownership
- Consider adding a CODEOWNERS file for the phlex-src tree so triage notifications reach the most appropriate maintainers.
-```
diff --git a/.github/REUSABLE_WORKFLOWS.md b/.github/REUSABLE_WORKFLOWS.md
index 8a912c44..7faf28d3 100644
--- a/.github/REUSABLE_WORKFLOWS.md
+++ b/.github/REUSABLE_WORKFLOWS.md
@@ -2,7 +2,7 @@
## Overview and General Instructions
-The workflows in `Framework-R-D/phlex/` maybe invoked as follows:
+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 (`@phlexbot `).
@@ -12,18 +12,18 @@ Additionally, you can configure your own fork of Phlex to run CI checks on local
If you are a Phlex-affiliated developer working on a dependent package of Phlex, or on a different Cetmodules-using package, or on Cetmodules itself, you may be able to invoke these workflows on your own project following the information in this guide. However, this is only supported for Phlex-affiliated developers, and even then on a best effort basis. We do **not** support or encourage others to utilize these workflows at this time.
-#### Running Workflows Manually (`workflow_dispatch`)
+### Running Workflows Manually (`workflow_dispatch`)
Most workflows in this repository can be run manually on any branch, tag, or commit. This is useful for testing changes without creating a pull request or for applying fixes to a specific branch.
To run a workflow manually:
-1. Navigate to the **Actions** tab of the Phlex repository (or your fork).
-1. In the left sidebar, click the workflow you want to run (e.g., **Clang-Format Check**).
-1. Above the list of workflow runs, you will see a banner that says "This workflow has a `workflow_dispatch` event trigger." Click the **Run workflow** dropdown on the right.
-1. Use the **Branch/tag** dropdown to select the branch you want to run the workflow on.
-1. Some workflows have additional inputs (e.g., the `cmake-build` workflow allows you to specify build combinations). Fill these out as needed.
-1. Click the **Run workflow** button.
+1. Navigate to the **Actions** tab of the Phlex repository (or your fork).
+1. In the left sidebar, click the workflow you want to run (e.g., **Clang-Format Check**).
+1. Above the list of workflow runs, you will see a banner that says "This workflow has a `workflow_dispatch` event trigger." Click the **Run workflow** dropdown on the right.
+1. Use the **Branch/tag** dropdown to select the branch you want to run the workflow on.
+1. Some workflows have additional inputs (e.g., the `cmake-build` workflow allows you to specify build combinations). Fill these out as needed.
+1. Click the **Run workflow** button.
### For Contributors Working on a Fork of Phlex
@@ -41,13 +41,13 @@ Once you have done this, you can trigger the auto-fix workflows by commenting on
For workflows that automatically commit fixes to pull requests (e.g., formatters), you must create a Personal Access Token (PAT) and add it as a secret to your repository.
1. **Create a PAT:** Follow the GitHub documentation to [create a fine-grained personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token).
- - Give it a descriptive name (e.g., `WORKFLOW_FIXES_PAT`).
- - Grant it the following repository permissions:
- - `Contents`: `Read and write`
- - `Pull requests`: `Read and write`
+ - Give it a descriptive name (e.g., `WORKFLOW_FIXES_PAT`).
+ - Grant it the following repository permissions:
+ - `Contents`: `Read and write`
+ - `Pull requests`: `Read and write`
2. **Add the PAT as a Repository Secret:**
- - In your repository, go to `Settings` > `Secrets and variables` > `Actions`.
- - Create a new repository secret named `WORKFLOW_PAT` and paste your PAT as the value.
+ - In your repository, go to `Settings` > `Secrets and variables` > `Actions`.
+ - Create a new repository secret named `WORKFLOW_PAT` and paste your PAT as the value.
### Calling a Reusable Workflow from a Different Repository
@@ -93,39 +93,39 @@ jobs:
#### All Inputs
-- `checkout-path` (string, optional): Path to check out code to.
-- `build-path` (string, optional): Path for build artifacts.
-- `skip-relevance-check` (boolean, optional, default: `false`): Bypass the check that only runs the build if C++ or CMake files have changed.
-- `build-combinations` (string, optional): A space-separated list of build combinations to run.
-- `ref` (string, optional): The branch or ref to check out.
-- `repo` (string, optional): The repository to check out from (e.g., `my-org/my-repo`).
-- `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.
+- `checkout-path` (string, optional): Path to check out code to.
+- `build-path` (string, optional): Path for build artifacts.
+- `skip-relevance-check` (boolean, optional, default: `false`): Bypass the check that only runs the build if C++ or CMake files have changed.
+- `build-combinations` (string, optional): A space-separated list of build combinations to run.
+- `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.
-### 2. `python-check.yaml`
+### 2. `cmake-format-check.yaml`
-Checks Python code for formatting and type errors using `ruff` and `mypy`.
+Checks CMake files for formatting issues using `gersemi`.
#### Usage Example
```yaml
jobs:
- check_python:
- uses: Framework-R-D/phlex/.github/workflows/python-check.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+ check_cmake_format:
+ uses: Framework-R-D/phlex/.github/workflows/cmake-format-check.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
```
#### 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 Python files have changed.
-- `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.
+- `checkout-path` (string, optional): Path to check out code to.
+- `skip-relevance-check` (boolean, optional, default: `false`): Bypass the check that only runs if CMake files have changed.
+- `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.
### 3. `cmake-format-fix.yaml`
Automatically formats CMake files using `gersemi` and commits the changes. Typically triggered by an `issue_comment`.
-#### Usage Example (in a workflow triggered by `issue_comment`)
+#### Usage Example
```yaml
name: 'Bot Commands'
@@ -153,24 +153,161 @@ jobs:
#### All Inputs
-- `checkout-path` (string, optional): Path to check out code to.
-- `ref` (string, **required**): The branch or ref to check out.
-- `repo` (string, **required**): The repository to check out from.
+- `checkout-path` (string, optional): Path to check out code to.
+- `ref` (string, **required**): The branch, ref, or SHA to check out.
+- `repo` (string, **required**): The repository to check out from.
+
+### 4. `python-check.yaml`
+
+Checks Python code for formatting and type errors using `ruff` and `mypy`.
+
+#### Usage Example
+
+```yaml
+jobs:
+ check_python:
+ uses: Framework-R-D/phlex/.github/workflows/python-check.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+```
+
+#### 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 Python files have changed.
+- `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.
-### 4. `python-fix.yaml`
+### 5. `python-fix.yaml`
Automatically formats and fixes Python code using `ruff` and commits the changes. Typically triggered by an `issue_comment`.
-#### Usage Example (in a workflow triggered by `issue_comment`)
+#### Usage Example
+
+```yaml
+name: 'Bot Commands'
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ fix-python:
+ # Run only on comments from collaborators/owners that start with the bot command
+ if: >
+ github.event.issue.pull_request &&
+ (github.event.comment.author_association == 'COLLABORATOR' || github.event.comment.author_association == 'OWNER') &&
+ startsWith(github.event.comment.body, format('@{0}bot python-fix', github.event.repository.name))
+ uses: Framework-R-D/phlex/.github/workflows/python-fix.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+ with:
+ # The ref and repo of the PR need to be retrieved and passed
+ ref: ${{ steps.get_pr_info.outputs.ref }}
+ repo: ${{ steps.get_pr_info.outputs.repo }}
+ secrets:
+ WORKFLOW_PAT: ${{ secrets.WORKFLOW_PAT }}
+```
+
+#### All Inputs
+
+- `checkout-path` (string, optional): Path to check out code to.
+- `ref` (string, **required**): The branch, ref, or SHA to check out.
+- `repo` (string, **required**): The repository to check out from.
+
+### 6. `markdown-check.yaml`
+
+Checks Markdown files for formatting issues using `markdownlint`.
+
+#### Usage Example
+
+```yaml
+jobs:
+ check_markdown:
+ uses: Framework-R-D/phlex/.github/workflows/markdown-check.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+```
+
+#### 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 Markdown files have changed. Note that this workflow automatically emulates the trigger type of the caller; it will run relevance checks if called from a `pull_request` or `push` event, and skip them (running on all files) otherwise.
+- `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.
+- `ref` (string, optional): The branch, ref, or SHA to check out.
+- `repo` (string, optional): The repository to check out from.
+
+### 7. `markdown-fix.yaml`
+
+Automatically formats Markdown files using `markdownlint` and commits the changes. Typically triggered by an `issue_comment`.
+
+#### Usage Example
+
+```yaml
+name: 'Bot Commands'
+on:
+ issue_comment:
+ types: [created]
+
+jobs:
+ fix-markdown:
+ # Run only on comments from collaborators/owners that start with the bot command
+ if: >
+ github.event.issue.pull_request &&
+ (github.event.comment.author_association == 'COLLABORATOR' || github.event.comment.author_association == 'OWNER') &&
+ (
+ startsWith(github.event.comment.body, format('@{0}bot format', github.event.repository.name)) ||
+ startsWith(github.event.comment.body, format('@{0}bot markdown-fix', github.event.repository.name))
+ )
+ uses: Framework-R-D/phlex/.github/workflows/markdown-fix.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+ with:
+ # The ref and repo of the PR need to be retrieved and passed
+ ref: ${{ steps.get_pr_info.outputs.ref }}
+ repo: ${{ steps.get_pr_info.outputs.repo }}
+ secrets:
+ WORKFLOW_PAT: ${{ secrets.WORKFLOW_PAT }}
+```
+
+#### All Inputs
+
+- `checkout-path` (string, optional): Path to check out code to.
+- `ref` (string, **required**): The branch, ref, or SHA to check out.
+- `repo` (string, **required**): The repository to check out from.
+
+### 8. `actionlint-check.yaml`
+
+Checks GitHub Actions workflow files for errors and best practices using `actionlint`.
+
+#### Usage Example
+
+```yaml
+jobs:
+ check_actions:
+ uses: Framework-R-D/phlex/.github/workflows/actionlint-check.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+```
+
+#### 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 workflow files have changed.
+- `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.
+
+### 9. `codeql-analysis.yaml`
-*Similar to `cmake-format-fix.yaml`, but triggered by a command like `@bot python-fix`.*
+Performs static analysis on the codebase using GitHub CodeQL to identify potential security vulnerabilities and coding errors.
+
+#### Usage Example
+
+```yaml
+jobs:
+ analyze:
+ uses: Framework-R-D/phlex/.github/workflows/codeql-analysis.yaml@cef968c52aab432b836bb28119a9661c82c8b0d1
+```
#### All Inputs
-- `checkout-path` (string, optional): Path to check out code to.
-- `ref` (string, **required**): The branch or ref to check out.
-- `repo` (string, **required**): The repository to check out from.
+- `checkout-path` (string, optional): Path to check out code to.
+- `build-path` (string, optional): Path for build artifacts.
+- `language-matrix` (string, optional, default: `'["cpp", "python", "actions"]'`): JSON array of languages to analyze.
+- `pr-number` (string, optional): PR number if run in PR context.
+- `pr-head-repo` (string, optional): The full name of the PR head repository.
+- `pr-base-repo` (string, optional): The full name of the PR base repository.
### Other Workflows
-The repository also provides `actionlint-check.yaml`, `cmake-format-check.yaml`, and `codeql-analysis.yaml`, which can be used in a similar manner.
+The repository also provides `clang-format-check.yaml`, `clang-format-fix.yaml`, `clang-tidy-check.yaml`, and `clang-tidy-fix.yaml`, which can be used in a similar manner.
diff --git a/.github/actions/detect-relevant-changes/action.yaml b/.github/actions/detect-relevant-changes/action.yaml
index 753a4e11..07ab8dbf 100644
--- a/.github/actions/detect-relevant-changes/action.yaml
+++ b/.github/actions/detect-relevant-changes/action.yaml
@@ -53,6 +53,7 @@ runs:
DEFAULT_TYPE_PATTERNS[cpp]=$'*.cpp\n*.hpp'
DEFAULT_TYPE_PATTERNS[cmake]=$'CMakeLists.txt\n*.cmake'
DEFAULT_TYPE_PATTERNS[python]=$'*.py'
+ DEFAULT_TYPE_PATTERNS[md]=$'*.md'
parse_list() {
local input="$1"
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 7ddbfb2c..b9b1e9c7 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -94,7 +94,7 @@ If the workspace root contains a `srcs/` directory, it may contain symbolic link
## Text Formatting Standards
-**CRITICAL: Apply to ALL files you create or edit (bash scripts, Python, C++, YAML, Markdown, etc.)**
+### CRITICAL: Apply to ALL files you create or edit (bash scripts, Python, C++, YAML, Markdown, etc.)
- All text files must have their final line be non-empty and terminated with a single newline character, leaving no trailing blank lines
- **Never add trailing whitespace on any line** (spaces or tabs at end of lines)
diff --git a/.github/workflows/markdown-check.yaml b/.github/workflows/markdown-check.yaml
new file mode 100644
index 00000000..70b725d8
--- /dev/null
+++ b/.github/workflows/markdown-check.yaml
@@ -0,0 +1,167 @@
+name: Markdown Check
+run-name: "${{ github.actor }} checking markdown format"
+
+permissions:
+ contents: read
+ pull-requests: read
+
+on:
+ pull_request:
+ branches: [ main, develop ]
+ workflow_dispatch:
+ inputs:
+ ref:
+ 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
+
+env:
+ local_checkout_path: ${{ (github.event_name == 'workflow_call' && inputs.checkout-path) || format('{0}-src', github.event.repository.name) }}
+
+jobs:
+ pre-check:
+ runs-on: ubuntu-latest
+ outputs:
+ is_act: ${{ steps.detect_act.outputs.is_act }}
+ steps:
+ - name: Detect act environment
+ id: detect_act
+ uses: Framework-R-D/phlex/.github/actions/detect-act-env@main
+
+ detect-changes:
+ needs: pre-check
+ if: >
+ needs.pre-check.outputs.is_act != 'true' &&
+ (
+ github.event_name == 'pull_request' ||
+ github.event_name == 'push' ||
+ (
+ github.event_name == 'workflow_call' &&
+ inputs.skip-relevance-check != 'true' &&
+ (github.event.pull_request || github.event.before)
+ )
+ )
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: read
+ outputs:
+ has_changes: ${{ steps.filter.outputs.matched }}
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ fetch-depth: 0
+ path: ${{ env.local_checkout_path }}
+ repository: ${{ (github.event_name == 'workflow_call' && inputs.repo) || github.repository }}
+
+ - name: Detect Markdown changes
+ id: filter
+ uses: Framework-R-D/phlex/.github/actions/detect-relevant-changes@main
+ with:
+ repo-path: ${{ env.local_checkout_path }}
+ base-ref: ${{ (github.event_name == 'workflow_call' && inputs.pr-base-sha) || github.event.pull_request.base.sha || github.event.before }}
+ head-ref: ${{ (github.event_name == 'workflow_call' && inputs.pr-head-sha) || github.event.pull_request.head.sha || github.sha }}
+ file-type: md
+
+ - name: Report detection outcome
+ run: |
+ if [ "${{ steps.filter.outputs.matched }}" != "true" ]; then
+ echo "::notice::No Markdown-related changes detected; formatting check will be skipped."
+ else
+ echo "::group::Markdown-related files"
+ printf '%s\n' "${{ steps.filter.outputs.matched_files }}"
+ echo "::endgroup::"
+ fi
+
+ markdown-check:
+ needs: [pre-check, detect-changes]
+ if: >
+ needs.detect-changes.result == 'skipped' ||
+ (
+ needs.detect-changes.result == 'success' &&
+ needs.detect-changes.outputs.has_changes == 'true'
+ )
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ ref: ${{ (github.event_name == 'workflow_call' && (inputs.ref || inputs.pr-head-sha)) || (github.event_name == 'workflow_dispatch' && github.event.inputs.ref) || github.ref }}
+ path: ${{ env.local_checkout_path }}
+ repository: ${{ (github.event_name == 'workflow_call' && inputs.repo) || github.repository }}
+
+ - name: Add problem matcher
+ uses: xt0rted/markdownlint-problem-matcher@b643b0751c371f357690337d4549221347c0e1bc # v1.1.0
+
+ - name: Run markdownlint
+ id: lint
+ uses: DavidAnson/markdownlint-cli2-action@8f3516061301755c97ff833a8e933f09282cc5b5 # v11.0.0
+ with:
+ globs: |
+ ${{ env.local_checkout_path }}/**/*.md
+ !${{ env.local_checkout_path }}/**/CHANGELOG.md
+ continue-on-error: true
+
+ - name: Evaluate markdownlint result
+ if: always() && steps.lint.outcome != 'skipped'
+ run: |
+ if [ "${{ steps.lint.outcome }}" = "success" ]; then
+ echo "✅ Markdown formatting check passed."
+ else
+ echo "::error::Markdown formatting check failed."
+ echo "::error::Comment '@${{ github.event.repository.name }}bot format' or '@${{ github.event.repository.name }}bot markdown-fix' on the PR to auto-fix."
+ exit 1
+ fi
+
+ markdown-check-skipped:
+ needs: [pre-check, detect-changes]
+ if: >
+ needs.pre-check.outputs.is_act != 'true' &&
+ (
+ github.event_name == 'pull_request' ||
+ github.event_name == 'push' ||
+ (
+ github.event_name == 'workflow_call' &&
+ inputs.skip-relevance-check != 'true' &&
+ (github.event.pull_request || github.event.before)
+ )
+ ) &&
+ (needs.detect-changes.result == 'success' && needs.detect-changes.outputs.has_changes != 'true')
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+
+ steps:
+ - name: No relevant Markdown changes detected
+ run: echo "::notice::No Markdown-related changes detected; markdown-check skipped."
diff --git a/.github/workflows/markdown-fix.yaml b/.github/workflows/markdown-fix.yaml
new file mode 100644
index 00000000..99bb6b82
--- /dev/null
+++ b/.github/workflows/markdown-fix.yaml
@@ -0,0 +1,92 @@
+name: Markdown Fix
+run-name: "${{ github.actor }} fixing markdown format"
+
+on:
+ issue_comment:
+ types:
+ - created
+ workflow_call:
+ inputs:
+ checkout-path:
+ description: "Path to check out code to"
+ required: false
+ type: string
+ ref:
+ description: "The branch or ref to checkout"
+ required: true
+ type: string
+ repo:
+ description: "The repository to checkout from"
+ required: true
+ type: string
+ workflow_dispatch:
+ inputs:
+ ref:
+ description: "The branch, ref, or SHA to checkout. Defaults to the repository's default branch."
+ required: false
+ type: string
+
+permissions:
+ pull-requests: write
+ contents: write
+
+env:
+ local_checkout_path: ${{ (github.event_name == 'workflow_call' && inputs.checkout-path) || format('{0}-src', github.event.repository.name) }}
+
+jobs:
+ pre-check:
+ runs-on: ubuntu-latest
+ name: Parse command
+ if: >
+ github.event_name == 'workflow_dispatch' ||
+ github.event_name == 'workflow_call' ||
+ (
+ github.event_name == 'issue_comment' &&
+ github.event.issue.pull_request &&
+ (
+ startsWith(github.event.comment.body, '@phlexbot format') ||
+ startsWith(github.event.comment.body, '@phlexbot markdown-fix') ||
+ startsWith(github.event.comment.body, format('@{0}bot format', github.event.repository.name)) ||
+ startsWith(github.event.comment.body, format('@{0}bot markdown-fix', github.event.repository.name))
+ )
+ )
+ outputs:
+ ref: ${{ (github.event_name == 'workflow_call' && inputs.ref) || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref)) || steps.get_pr.outputs.ref }}
+ repo: ${{ (github.event_name == 'workflow_call' && inputs.repo) || (github.event_name == 'workflow_dispatch' && github.repository) || steps.get_pr.outputs.repo }}
+
+ steps:
+ - name: Get PR Info
+ if: github.event_name == 'issue_comment'
+ id: get_pr
+ uses: Framework-R-D/phlex/.github/actions/get-pr-info@main
+
+ apply_fixes:
+ runs-on: ubuntu-latest
+ name: Apply fixes
+ needs: pre-check
+ if: needs.pre-check.result == 'success'
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ path: ${{ env.local_checkout_path }}
+ ref: ${{ needs.pre-check.outputs.ref }}
+ repository: ${{ needs.pre-check.outputs.repo }}
+ token: ${{ secrets.WORKFLOW_PAT }}
+
+ - name: Run markdownlint
+ uses: DavidAnson/markdownlint-cli2-action@8f3516061301755c97ff833a8e933f09282cc5b5 # v11.0.0
+ with:
+ globs: |
+ ${{ env.local_checkout_path }}/**/*.md
+ !${{ env.local_checkout_path }}/**/CHANGELOG.md
+ fix: true
+
+ - name: Handle fix commit
+ uses: Framework-R-D/phlex/.github/actions/handle-fix-commit@main
+ with:
+ tool: markdownlint
+ working-directory: ${{ env.local_checkout_path }}
+ token: ${{ secrets.WORKFLOW_PAT }}
+ pr-info-ref: ${{ needs.pre-check.outputs.ref }}
+ pr-info-repo: ${{ needs.pre-check.outputs.repo }}
diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc
new file mode 100644
index 00000000..9877b48d
--- /dev/null
+++ b/.markdownlint.jsonc
@@ -0,0 +1,16 @@
+{
+ "default": true,
+ "MD012": true,
+ "MD013": false,
+ "MD022": true,
+ "MD024": {
+ "siblings_only": true
+ },
+ "MD031": true,
+ "MD032": true,
+ "MD034": true,
+ "MD036": {
+ "punctuation": ".,;:!?"
+ },
+ "MD040": true
+}
diff --git a/CLANG_TIDY_CONFIGURATION.md b/CLANG_TIDY_CONFIGURATION.md
index 701c1d53..e2a589f9 100644
--- a/CLANG_TIDY_CONFIGURATION.md
+++ b/CLANG_TIDY_CONFIGURATION.md
@@ -198,7 +198,7 @@ These targets:
The clang-tidy workflows complement the existing formatting workflows:
-- **Format checks:** `@phlexbot format` - Fixes C++ and CMake formatting
+- **Format checks:** `@phlexbot format` - Fixes C++, CMake, and Markdown formatting
- **Tidy checks:** `@phlexbot tidy-fix` - Fixes Core Guidelines violations
Both can be run independently or together as needed.
diff --git a/DEVELOPING.md b/DEVELOPING.md
index 48d31a78..9ef73b1a 100644
--- a/DEVELOPING.md
+++ b/DEVELOPING.md
@@ -2,7 +2,8 @@
## Contributions
-_[The contribution policy is currently under development.]_
+> [!NOTE]
+> The contribution policy is currently under development.
Except in rare circumstances, changes to the `phlex` repository are proposed and considered through GitHub pull requests (PRs).
@@ -114,7 +115,6 @@ The project automatically runs coverage analysis on every PR and push to main/de
Coverage reports are uploaded to Codecov for tracking and PR integration, with automatic comments on PRs showing coverage changes.
-
## On GitHub Copilot
The `.github/copilot-instructions.md` contains various "ground rules" to be observed by GitHub Copilot for every session. They are intended to be useful for everyone, but you can override or augment them yourself by creating a `/.github/copilot-instructions.md` file. If this file exists, its contents will be merged with—but take precedence over—the repository level instructions.
diff --git a/INSTALLATION.md b/INSTALLATION.md
index ce859525..c03da9cb 100644
--- a/INSTALLATION.md
+++ b/INSTALLATION.md
@@ -1,4 +1,4 @@
-## Overview
+# Overview
These instructions are intended to get users (not developers) of Phlex to a working environment, starting from scratch.
This is not the only way in which this can be done, but this method has been verified on the primary supported OS (Alma Linux 9) and will be supported by the Phlex development team on that platform.
@@ -7,7 +7,7 @@ We assume that you do *not* have an installation of Spack already.
We only support Spack v1.0 and newer, so if you have an older version of Spack we recommend installation of a new one according to these instructions.
If you already have a new-enough version of Spack installed, you can skip to step 6.
-### Installing Spack
+## Installing Spack
Step 1: create a working directory for phlex use:
@@ -22,9 +22,11 @@ cd ${PHLEX_WORK_DIR}
```
Then make sure you don't already have a spack command on your PATH:
-```bash
+
+```bash
which spack
```
+
should tell you there is no spack in your PATH.
Step 2: install Spack
@@ -32,13 +34,16 @@ Step 2: install Spack
```bash
git clone --depth=2 https://github.com/spack/spack.git
```
+
If you encounter trouble, consult the [installation instructions from the Spack project]( https://spack-tutorial.readthedocs.io/en/latest/tutorial_basics.html#basics-tutorial).
Step 3: make spack available at the command line.
+
```bash
source ${PHLEX_WORK_DIR}/spack/share/spack/setup-env.sh
```
-`which spack` will show that `spack` is a bash function.
+
+`which spack` will show that `spack` is a bash function.
Step 4: run the `spack bootstrap now` command to make sure that `${HOME}/.spack` exists and is populated properly.
@@ -48,11 +53,13 @@ Step 5: Modify the Spack configuration to avoid filling `/tmp`.
This is not at all related to Phlex, but until there is spack documentation describing this, we recommend it as good practice.
Run the following, which will open an editor.
+
```bash
spack config edit config
```
+
Modify the file to include a new key, `build_stage`.
-`config` key may already be in the file and may already contain other keys.
+`config` key may already be in the file and may already contain other keys.
Pay careful attention to the indentation and spacing; YAML is sensitive to these.
```yaml
@@ -61,10 +68,10 @@ config:
- $spack/var/spack/stage
```
-### Ensuring a sufficient compiler
+## Ensuring a sufficient compiler
Step 6: ensure that spack has access to a new enough GCC.
-Currently this means GCC 14.
+Currently this means GCC 14.
Run `spack compilers` to see what compilers Spack knows about.
It may tell you to run `spack compiler find` to autodetect compilers.
@@ -76,9 +83,9 @@ If you don't have GCC 14 or newer, then install GCC 14:
spack install -j 12 gcc@14 # choose a suitable number of jobs for your machine
```
-Building GCC may take a while (30 minutes or so on a 12 core machine).
+Building GCC may take a while (30 minutes or so on a 12 core machine).
-### Creating and installing the Phlex environment
+## Creating and installing the Phlex environment
Step 7: Add the Spack recipe repositories needed by Phlex:
@@ -114,4 +121,3 @@ Thus the full installation may take a few hours.
When the installation is complete, you should find that the `phlex` executable is on your PATH.
`which phlex` will verify this.
-
diff --git a/README.md b/README.md
index c82ad405..b17293ba 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,6 @@ Once you have Phlex installed, you can start creating algorithms and using them
[A repository with example user code](https://github.com/framework-r-d/phlex-examples) is available to help you get started.
Clone that repository and follow the instructions there to begin using Phlex.
-
## Developing Phlex
Instructions for the development of Phlex itself are in the [developer notes](DEVELOPING.md)
diff --git a/form/README.md b/form/README.md
index bfc65c74..a84ae053 100644
--- a/form/README.md
+++ b/form/README.md
@@ -10,8 +10,9 @@ Prototype development for I/O infrastructure supporting Phlex
`./test/form/phlex_writer ; ls -l toy.root`
-## ROOT checks:
-```
+## ROOT checks
+
+```cpp
TFile* file = TFile::Open("toy.root")
file->ls()
TTree* tree1 = (TTree*)file->Get("");
@@ -22,6 +23,6 @@ tree1->Scan()
tree2->Scan()
```
-# run reader
+## run reader
`./test/form/phlex_reader`
diff --git a/scripts/README.md b/scripts/README.md
index c21e9167..6a32f118 100644
--- a/scripts/README.md
+++ b/scripts/README.md
@@ -53,7 +53,7 @@ The script automatically detects and adapts to:
Configure the script behavior by setting these variables **before** sourcing:
| Variable | Description | Example |
-|----------|-------------|---------|
+| :--- | :--- | :--- |
| `PHLEX_SPACK_ROOT` | Path to Spack installation | `export PHLEX_SPACK_ROOT=/opt/spack` |
| `PHLEX_SPACK_ENV` | Spack environment to activate | `export PHLEX_SPACK_ENV=phlex-dev` |
| `PHLEX_BUILD_DIR` | Build directory location | `export PHLEX_BUILD_DIR=/tmp/phlex-build` |
@@ -165,7 +165,7 @@ Provides convenient commands for managing code coverage analysis.
#### Commands
| Command | Description |
-|---------|-------------|
+| :--- | :--- |
| `setup` | Configure and build with coverage instrumentation |
| `clean` | Remove coverage data files (C++ and Python) |
| `test` | Run tests with coverage collection (C++ and Python) |