From 71ec9b51ebfcc142f642ed1d04791df58cc9665e Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Wed, 3 Jun 2026 10:43:54 -0700 Subject: [PATCH 1/2] Smoke-test only the PR base branch In smoke mode, restrict the matrix to the PR base branch (github.base_ref) via a new smoke_branch input, so a PR onto develop validates the develop image rows and a PR onto main validates the main rows -- 2 builds instead of 4, while still covering the correct branch. Empty smoke_branch (e.g. workflow_dispatch) falls back to building both branches. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/build-docker-task.yml | 28 ++++++++++++++++--------- .github/workflows/test-pull-request.yml | 4 ++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-docker-task.yml b/.github/workflows/build-docker-task.yml index 104e4ed..2a6f7be 100644 --- a/.github/workflows/build-docker-task.yml +++ b/.github/workflows/build-docker-task.yml @@ -15,6 +15,14 @@ on: required: false type: boolean default: false + # In smoke mode, restrict the build to this branch's rows (the PR + # base branch). Empty builds both branches' rows. Lets a PR onto + # develop smoke-test the develop images and a PR onto main the main + # images, without building the other branch. + smoke_branch: + required: false + type: string + default: '' # Branch to check out and whose images to build/push. Empty uses the # triggering ref (PR context). The publisher passes main and develop # so both branches' tags are produced from one scheduled run. @@ -49,27 +57,27 @@ jobs: id: getmatrix env: SMOKE: ${{ inputs.smoke }} + SMOKE_BRANCH: ${{ inputs.smoke_branch }} REF: ${{ inputs.ref }} run: | - # $ref below is a jq variable (passed via --arg), not a shell - # variable, so it must stay single-quoted / unexpanded. + # $ref and $sb below are jq variables (passed via --arg), not shell + # variables, so they must stay single-quoted / unexpanded. # shellcheck disable=SC2016 if [[ "$SMOKE" == "true" ]]; then - # One Ubuntu + one LSIO variant per branch exercises the shared - # Dockerfile build logic and each branch's build args; tags are - # irrelevant since smoke never pushes. De-dup by name+branch so a - # PR targeting develop still validates the develop rows. - FILTER='.Images |= (map(select(.Name == "NxMeta" or .Name == "NxMeta-LSIO")) | unique_by([.Name, .Branch]))' + # One Ubuntu + one LSIO variant exercises the shared Dockerfile + # build logic and the branch's build args; tags are irrelevant + # since smoke never pushes. Restrict to the PR base branch ($sb) + # so a PR onto develop validates the develop rows and a PR onto + # main validates the main rows; empty $sb builds both branches. + FILTER='.Images |= (map(select((.Name == "NxMeta" or .Name == "NxMeta-LSIO") and ($sb == "" or .Branch == $sb))) | unique_by([.Name, .Branch]))' elif [[ -n "$REF" ]]; then # Publish: build only the rows targeting the branch being built # (avoids building the other branch's rows just to discard them). - # $ref is passed via --arg so the value is never interpolated - # into the jq program. FILTER='.Images |= map(select(.Branch == $ref))' else FILTER='.' fi - echo "matrix=$(jq --arg ref "$REF" --compact-output "$FILTER" ./Make/Matrix.json)" >> "$GITHUB_OUTPUT" + echo "matrix=$(jq --arg ref "$REF" --arg sb "$SMOKE_BRANCH" --compact-output "$FILTER" ./Make/Matrix.json)" >> "$GITHUB_OUTPUT" get-version: name: Get version information job diff --git a/.github/workflows/test-pull-request.yml b/.github/workflows/test-pull-request.yml index a3b5cb0..07b3372 100644 --- a/.github/workflows/test-pull-request.yml +++ b/.github/workflows/test-pull-request.yml @@ -53,6 +53,9 @@ jobs: # scheduled publish-release.yml, so a smoke pass is fast PR feedback, # not a publish gate. # + # smoke_branch targets the PR base branch so a PR onto develop validates + # the develop image rows and a PR onto main validates the main rows. + # # build_base is only enabled when a base Dockerfile changed: the product # smoke build pulls the published base from Docker Hub, so building the # base otherwise is wasted work. When a base Dockerfile does change, build @@ -66,6 +69,7 @@ jobs: with: push: false smoke: true + smoke_branch: ${{ github.base_ref }} build_base: ${{ needs.changes.outputs.base == 'true' }} # TODO: Workaround for GitHub Actions not supporting status checks on conditional jobs From 784717ba549e4b9c41d2684e18aeaa774d6a7aff Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Wed, 3 Jun 2026 10:43:54 -0700 Subject: [PATCH 2/2] Move VS Code recommendations to the workspace file Remove .vscode/extensions.json; the extension recommendations already live in NxWitness.code-workspace, where all VS Code customizations belong. Update AGENTS.md (new "Workspace and linting" section) and copilot-instructions.md to reference the workspace file and note the convention (open the workspace file, not the folder, so its settings and recommendations apply). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/copilot-instructions.md | 2 +- .vscode/extensions.json | 17 ----------------- AGENTS.md | 13 +++++-------- 3 files changed, 6 insertions(+), 26 deletions(-) delete mode 100644 .vscode/extensions.json diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 4fa4d55..c1bb4d5 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -43,7 +43,7 @@ This repository builds and publishes Docker images for Network Optix VMS product - Pull requests run unit tests and style checks, plus a fast smoke build (NxMeta and NxMeta-LSIO, amd64 only, no push) that runs only when image files change -- not the full matrix. - Publishing is schedule/manual only via `publish-release.yml`, which builds the base images once and then publishes the full matrix for both the `main` and `develop` branches in a single run. - Merges to `main`/`develop` do not publish; auto-merged Dependabot and codegen PRs are picked up by the next scheduled publish. Do not reintroduce push-triggered publishing or full-matrix PR builds. -- Structured files are linted in-editor via the workspace-recommended extensions in [.vscode/extensions.json](../.vscode/extensions.json) (C#, Markdown, YAML, Docker, GitHub Actions) rather than a CI lint job; lint changed files before pushing, and run `actionlint` for deeper workflow checks. See AGENTS.md. +- Structured files are linted in-editor via the extensions recommended in the workspace file `NxWitness.code-workspace` (C#, Markdown, Docker, GitHub Actions, spelling) rather than a CI lint job; lint changed files before pushing, and run `actionlint` for deeper workflow checks. VS Code customizations belong in the workspace file, not under `.vscode/`. See AGENTS.md. ## What to Keep in Sync diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ac10479..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "recommendations": [ - // C#: language server + formatter (also enforced by Husky/dotnet format) - "ms-dotnettools.csharp", - "csharpier.csharpier-vscode", - // Shared editor/format conventions from .editorconfig - "editorconfig.editorconfig", - // Markdown linting (README.md, HISTORY.md, docs) - "davidanson.vscode-markdownlint", - // YAML schema validation (compose files, workflow YAML) - "redhat.vscode-yaml", - // Dockerfile and Docker Compose linting - "ms-azuretools.vscode-docker", - // GitHub Actions workflow validation and expression linting - "github.vscode-github-actions" - ] -} diff --git a/AGENTS.md b/AGENTS.md index b683a9a..967650f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,14 +41,11 @@ For comprehensive coding and formatting standards, follow: - C# code should be formatted with CSharpier, then verified with `dotnet format` (style). - The `.Net Format` VS Code task in `.vscode/tasks.json` must be clean and warning-free at all times. -### Linting structured files +### Workspace and linting -- Every structured file type has a linter configured in the workspace via the recommended VS Code extensions in `.vscode/extensions.json`; there is no separate CI lint job. Lint changed files and clear reported problems before pushing. Coverage: - - C# — Roslyn analyzers + CSharpier (also enforced by Husky/`dotnet format`). - - Markdown — markdownlint (`README.md`, `HISTORY.md`, docs). - - YAML — Red Hat YAML schema validation (compose and workflow files). - - Dockerfiles / Docker Compose — the Docker extension. - - GitHub Actions workflows — the GitHub Actions extension (schema + expression checks); for deeper checks (including shellcheck on `run:` steps) run the `actionlint` CLI. +- VS Code customizations (settings, extension recommendations, spell-check words) live in the workspace file `NxWitness.code-workspace`, not under `.vscode/`. Add new editor settings or recommended extensions there. Open the workspace file in VS Code (not the folder) so those settings and recommendations apply. +- Every structured file type is linted in-editor via the extensions recommended in `NxWitness.code-workspace` (C#, Markdown, Dockerfiles/Compose, GitHub Actions, spelling, etc.); there is no separate CI lint job. Lint changed files and clear reported problems before pushing. +- For workflow files, the GitHub Actions extension covers schema/expression checks in-editor; run the `actionlint` CLI for deeper checks (including shellcheck on `run:` steps). ## Image Architecture @@ -60,7 +57,7 @@ For comprehensive coding and formatting standards, follow: - Pull requests (`test-pull-request.yml`) run unit tests and code style, plus a fast smoke build only when image files (`Docker/**`, `Make/Matrix.json`, `Make/Version.json`) change. The smoke build (`build-docker-task.yml` with `smoke: true`) builds a representative subset (NxMeta and NxMeta-LSIO, amd64 only, no push), not the full matrix. - Publishing happens only on a schedule or manual dispatch (`publish-release.yml`): it builds the base images once, then builds and pushes the full matrix for both the `main` and `develop` branches (`build-docker-task.yml` with `ref:` and `build_base: false`), and updates the GitHub release, Docker Hub readme, and date badge. - Merges to `main`/`develop` do not build or publish images. Auto-merged Dependabot and codegen PRs simply land commits that the next scheduled publish picks up. Do not reintroduce push-triggered publishing or full-matrix PR builds. -- Lint workflow edits before pushing (see [Linting structured files](#linting-structured-files)); there is no CI lint job. +- Lint workflow edits before pushing (see [Workspace and linting](#workspace-and-linting)); there is no CI lint job. ## Pull Request Review Process