diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 68cdecab..c6574309 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -17,7 +17,7 @@ "rollForward": false }, "dotnet-outdated-tool": { - "version": "4.7.2", + "version": "4.8.0", "commands": [ "dotnet-outdated" ], diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 4fa4d55f..10073221 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. Editor settings, extension recommendations, and spell-check words belong in the workspace file (not `.vscode/`). See AGENTS.md. ## What to Keep in Sync diff --git a/.github/workflows/build-docker-task.yml b/.github/workflows/build-docker-task.yml index 104e4ed0..2a6f7be6 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 a3b5cb0f..07b33728 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 diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index ac104794..00000000 --- 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 b683a9af..87ba12f7 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 settings, extension recommendations, and spell-check words live in the workspace file `NxWitness.code-workspace`; add new editor settings or recommended extensions there rather than in `.vscode/`. (Build/debug tasks still live in `.vscode/tasks.json` and `.vscode/launch.json`.) Open the workspace file in VS Code (not the folder) so its settings and recommendations apply. +- Linting is editor-only (no CI lint job); the extensions recommended in `NxWitness.code-workspace` cover the project's structured files: C# (Roslyn + CSharpier), Markdown, Dockerfiles/Compose, GitHub Actions workflows, and spelling. 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