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
18 changes: 16 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,51 @@
# GitHub Copilot Guidance

## Purpose

This file summarizes the solution and defines the hierarchy of guidance for AI-assisted contributions.

## Guidance Hierarchy (Must Follow)

1. [CODESTYLE.md](../CODESTYLE.md) is the master code style and formatting authority.
2. [AGENTS.md](../AGENTS.md) is secondary guidance describing the solution, workflows, and conventions.
3. Repository configuration files such as [`.editorconfig`](../.editorconfig) and [`.vscode/tasks.json`](../.vscode/tasks.json) define enforced formatting, line endings, and task expectations.

If any instruction conflicts, follow CODESTYLE.md first, then AGENTS.md.

## Solution Summary
This repository builds and publishes Docker images for Network Optix VMS products (Nx Witness, Nx Meta, Nx Go, DW Spectrum, Wisenet WAVE). It includes a .NET tooling project that generates Dockerfiles, matrices, and version inputs used by CI and packaging scripts.

This repository builds and publishes Docker images for Network Optix VMS products (Nx Witness, Nx Meta, Nx Go, DW Spectrum, Wisenet WAVE). It includes base images (nx-base, nx-base-lsio) and derived product images, plus a .NET tooling project that generates Dockerfiles, matrices, and version inputs used by CI and packaging scripts.

### Core Projects

- `CreateMatrix` (.NET 10 console app): Generates Dockerfiles and build matrix data using version and release metadata.
- `CreateMatrixTests` (xUnit v3 + AwesomeAssertions): Validates release handling and version forwarding.

### Key Inputs and Outputs

- Inputs: version and matrix data in `version.json`, [Make/Version.json](../Make/Version.json), and [Make/Matrix.json](../Make/Matrix.json).
- Outputs: Dockerfiles in [Docker/](../Docker/) and compose/test artifacts in [Make/](../Make/).
- Outputs: Dockerfiles in [Docker/](../Docker/) (base images and derived product images) and compose/test artifacts in [Make/](../Make/).
- Templates: Unraid container templates in [Unraid/](../Unraid/).

### Build and Validation Workflow (High Level)

- Primary entry points are the `CreateMatrix` CLI commands (version, matrix, make) run directly or via scripts in [Make/](../Make/).
- Formatting and style verification are enforced by CSharpier and dotnet format, with Husky.Net hooks.
- The `.Net Format` VS Code task in [`.vscode/tasks.json`](../.vscode/tasks.json) must be clean and warning-free at all times.

### Image Architecture

- Base images (`nx-base`, `nx-base-lsio`) are built and pushed, then used as `FROM` images for derived product Dockerfiles.
- Derived images should track base image tag changes (for example, the Ubuntu distro tag) to keep builds consistent.

## What to Keep in Sync

- Generated Dockerfiles and scripts must reflect CreateMatrix behavior.
- Base image Dockerfiles and derived image Dockerfiles should remain aligned since derived images build on the base images.
- Documentation in [README.md](../README.md) and release notes should align with current outputs and supported product variants.

## Expectations for Changes

- Follow the zero-warnings policy and formatting requirements in [CODESTYLE.md](../CODESTYLE.md).
- Use explicit types (no `var`), Allman braces, file-scoped namespaces, and other conventions as defined in the master style guide.
- Respect line endings and encoding rules from the repository configuration, including UTF-8 without BOM.
67 changes: 67 additions & 0 deletions .github/workflows/build-base-images-task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Build base images task

on:
workflow_call:
inputs:
push:
required: false
type: boolean
default: true

jobs:

build-base:
name: Build base image job
runs-on: ubuntu-latest

strategy:
matrix:
base:
- name: nx-base
dockerfile: Docker/NxBase.Dockerfile
tags: |
docker.io/ptr727/nx-base:ubuntu-noble
- name: nx-base-lsio
dockerfile: Docker/NxBase-LSIO.Dockerfile
tags: |
docker.io/ptr727/nx-base-lsio:ubuntu-noble

steps:

- name: Checkout step
uses: actions/checkout@v6

- name: Setup QEMU step
uses: docker/setup-qemu-action@v3
with:
platforms: linux/amd64,linux/arm64

- name: Setup Buildx step
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64

- name: Login to Docker Hub step
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Docker build and push base step
uses: docker/build-push-action@v6
with:
push: ${{ inputs.push && (github.ref_name == 'main' || github.ref_name == 'develop') }}
context: Docker
file: ${{ matrix.base.dockerfile }}
platforms: linux/amd64,linux/arm64
tags: ${{ matrix.base.tags }}
cache-from: |
type=registry,ref=${{ matrix.base.tags }}
type=gha,scope=develop-base-${{ matrix.base.name }}
type=gha,scope=main-base-${{ matrix.base.name }}
${{ github.event.pull_request && format('type=gha,scope=pr-base-{0}-{1}', github.event.pull_request.number, matrix.base.name) || '' }}
cache-to: |
${{ inputs.push && (github.ref_name == 'main' || github.ref_name == 'develop') && format('type=gha,mode=max,scope={0}-base-{1}', github.ref_name, matrix.base.name) || '' }}
${{ inputs.push && (github.ref_name == 'main' || github.ref_name == 'develop') && 'type=inline' || '' }}
${{ github.event.pull_request && !github.event.pull_request.head.repo.fork && format('type=gha,mode=max,scope=pr-base-{0}-{1}', github.event.pull_request.number, matrix.base.name) || '' }}
5 changes: 1 addition & 4 deletions .github/workflows/build-datebadge-task.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
name: Build BYOB date badge task

env:
IS_MAIN_BRANCH: ${{ endsWith(github.ref, 'refs/heads/main') }}

on:
workflow_call:

Expand All @@ -20,7 +17,7 @@ jobs:
echo "date=$(date)" >> $GITHUB_OUTPUT

- name: Build BYOB date badge step
if: ${{ env.IS_MAIN_BRANCH == 'true' }}
if: ${{ github.ref_name == 'main' }}
uses: RubbaBoy/BYOB@v1
with:
name: lastbuild
Expand Down
29 changes: 18 additions & 11 deletions .github/workflows/build-docker-task.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
name: Build Docker image task

env:
IS_MAIN_BRANCH: ${{ endsWith(github.ref, 'refs/heads/main') }}
DOCKER_REGISTRY: docker.io

on:
workflow_call:
inputs:
# Input to control whether to push the Docker image to Docker Hub
push:
required: false
type: boolean
Expand All @@ -28,7 +24,6 @@ jobs:

- name: Load matrix.json step
id: getmatrix
# Create compact version of matrix.json
run: |
echo "matrix=$(jq --compact-output '.' ./Make/Matrix.json)" >> $GITHUB_OUTPUT

Expand All @@ -37,10 +32,17 @@ jobs:
uses: ./.github/workflows/get-version-task.yml
secrets: inherit

build-base:
name: Build base image job
uses: ./.github/workflows/build-base-images-task.yml
with:
push: ${{ inputs.push }}
secrets: inherit

build-docker:
name: Build Docker image job
runs-on: ubuntu-latest
needs: [get-version, get-matrix]
needs: [get-version, get-matrix, build-base]

strategy:
max-parallel: 4
Expand All @@ -65,7 +67,7 @@ jobs:
- name: Login to Docker Hub step
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

Expand All @@ -83,15 +85,20 @@ jobs:
echo "LABEL_VERSION=${{ needs.get-version.outputs.SemVer2 }}"
echo "EOF"
} >> "$GITHUB_OUTPUT"

- name: Docker build and push step
uses: docker/build-push-action@v6
with:
push: ${{ inputs.push && (github.ref_name == matrix.images.Branch)}}
cache-from: type=gha,scope=${{ matrix.images.CacheScope }}
cache-to: type=gha,mode=max,scope=${{ matrix.images.CacheScope }}
push: ${{ inputs.push && (github.ref_name == matrix.images.Branch) }}
context: Docker
file: Docker/${{ matrix.images.Name }}.Dockerfile
platforms: linux/amd64,linux/arm64
tags: ${{ steps.tagsargs.outputs.tags }}
build-args: ${{ steps.tagsargs.outputs.args }}
cache-from: |
type=gha,scope=develop-${{ matrix.images.Name }}
type=gha,scope=main-${{ matrix.images.Name }}
${{ github.event.pull_request && format('type=gha,scope=pr-{0}-{1}', github.event.pull_request.number, matrix.images.Name) || '' }}
cache-to: |
${{ (github.ref_name == 'main' || github.ref_name == 'develop') && format('type=gha,mode=max,scope={0}-{1}', github.ref_name, matrix.images.Name) || '' }}
${{ github.event.pull_request && !github.event.pull_request.head.repo.fork && format('type=gha,mode=max,scope=pr-{0}-{1}', github.event.pull_request.number, matrix.images.Name) || '' }}
9 changes: 1 addition & 8 deletions .github/workflows/build-release-task.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
name: Build project release task

env:
IS_MAIN_BRANCH: ${{ endsWith(github.ref, 'refs/heads/main') }}

on:
workflow_call:
inputs:
# Input to control whether to create a GitHub release
github:
required: false
type: boolean
default: false
# Input to control whether to push the Docker image to Docker Hub
dockerhub:
required: false
type: boolean
Expand All @@ -29,12 +24,10 @@ jobs:
uses: ./.github/workflows/build-docker-task.yml
secrets: inherit
with:
# Conditional push to Docker Hub
push: ${{ inputs.dockerhub }}

github-release:
name: Publish GitHub release job
# Conditional GitHub release
if: ${{ inputs.github }}
runs-on: ubuntu-latest
needs: [get-version, build-docker]
Expand All @@ -49,7 +42,7 @@ jobs:
with:
generate_release_notes: true
tag_name: ${{ needs.get-version.outputs.SemVer2 }}
prerelease: ${{ env.IS_MAIN_BRANCH != 'true' }}
prerelease: ${{ github.ref_name != 'main' }}
files: |
LICENSE
README.md
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/get-version-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Get version information task
on:
workflow_call:
outputs:
# Version information outputs
SemVer2:
value: ${{ jobs.get-version.outputs.SemVer2 }}
AssemblyVersion:
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/publish-docker-readme-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ jobs:

- name: Load matrix.json step
id: getrepos
# Create array of docker hub repositories from matrix.json
run: |
echo "repos=$(jq --compact-output '[.Images[].Name | ascii_downcase | \"ptr727/\\(.)\"] | sort | unique' ./Make/Matrix.json)" >> "$GITHUB_OUTPUT"
echo "repos=$(jq --compact-output '[.Images[].Name | ascii_downcase | "ptr727/\(.)" ] + ["ptr727/nx-base","ptr727/nx-base-lsio"] | sort | unique' ./Make/Matrix.json)" >> "$GITHUB_OUTPUT"

publish-readme:
name: Publish docker hub readme job
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/publish-periodic-docker-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Publish weekly Docker image to Docker Hub action
on:
workflow_dispatch:
schedule:
# Run weekly on Mondays at 02:00 UTC
- cron: '0 2 * * MON'

concurrency:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
permissions:
contents: write
with:
# Publish
github: true
dockerhub: true

Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/run-codegen-pull-request-task.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
name: Run codegen and pull request task

env:
PROJECT_FILE: ./CreateMatrix/CreateMatrix.csproj
CODEGEN_ARGS: matrix --versionpath=./Make/Version.json --matrixpath=./Make/Matrix.json --updateversion

on:
workflow_call:

Expand All @@ -25,8 +21,8 @@ jobs:

- name: Run codegen step
run: >-
dotnet run --project ${{ env.PROJECT_FILE }} --
${{ env.CODEGEN_ARGS }}
dotnet run --project ./CreateMatrix/CreateMatrix.csproj --
matrix --versionpath=./Make/Version.json --matrixpath=./Make/Matrix.json --updateversion

- name: Format code step
run: |
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/run-periodic-codegen-pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ name: Run weekly CodeGen and Pull Request action
on:
workflow_dispatch:
schedule:
# Run weekly on Sundays at 02:00 UTC
- cron: '0 2 * * SUN'

concurrency:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/test-release-task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@ jobs:
uses: ./.github/workflows/build-release-task.yml
secrets: inherit
with:
# Do not publish
github: false
dockerhub: false
34 changes: 20 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Instructions for AI Coding Agents

This repository builds and publishes Docker images for Network Optix VMS products (Nx Witness, Nx Meta, Nx Go, DW Spectrum, Wisenet WAVE). It includes a .NET tooling project that generates Dockerfiles and build matrices, plus scripts and templates for packaging.
This repository builds and publishes Docker images for Network Optix VMS products (Nx Witness, Nx Meta, Nx Go, DW Spectrum, Wisenet WAVE). It includes base images (nx-base, nx-base-lsio) and derived product images that use the base images, plus a .NET tooling project that generates Dockerfiles and build matrices and scripts/templates for packaging.

For comprehensive coding and formatting standards, follow:

Expand All @@ -19,27 +19,32 @@ For comprehensive coding and formatting standards, follow:
- `CreateMatrixTests/CreateMatrixTests.csproj`
- xUnit v3 test project with AwesomeAssertions.

### Key Directories
- `Docker/`
- Generated and static Dockerfiles for product variants.
### Key Directories

- `Docker/`
- Generated and static Dockerfiles for base images and product variants.
- `Make/`
- Build orchestration scripts and test compose files.
- `Unraid/`
- Unraid container templates.
- `version.json`, `Make/Version.json`, `Make/Matrix.json`
- Version and matrix inputs consumed by the build pipeline.

## Build and Validation Workflow
## Build and Validation Workflow

- Primary developer entry points are the `CreateMatrix` CLI commands invoked directly or via the scripts in `Make/`:
- `version --versionpath=./Make/Version.json`.
- `matrix --versionpath=./Make/Version.json --matrixpath=./Make/Matrix.json --updateversion`.
- `make --versionpath=./Make/Version.json --makedirectory=./Make --dockerdirectory=./Docker --versionlabel=Beta`.
- Formatting and style checks are enforced by Husky.Net and VS Code tasks.
- Required tasks are documented in `CODESTYLE.md` and `.husky/task-runner.json`.
- 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.
- Formatting and style checks are enforced by Husky.Net and VS Code tasks.
- Required tasks are documented in `CODESTYLE.md` and `.husky/task-runner.json`.
- 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.

## Image Architecture

- Base images (`nx-base`, `nx-base-lsio`) are built and pushed, then reused as `FROM` images for derived product Dockerfiles.
- Derived product images should stay aligned with the base image changes and tags (for example, the Ubuntu distro tag).

## Coding Conventions (Highlights)

Expand All @@ -49,7 +54,8 @@ For comprehensive coding and formatting standards, follow:
- UTF-8 encoding without BOM.
- Respect line ending rules in `.editorconfig`.

## Notes for Changes

- When modifying Dockerfiles or build scripts, ensure generated outputs stay in sync with `CreateMatrix` behavior.
- Keep `README.md` and release documentation aligned with build outputs and product variants.
## Notes for Changes

- When modifying Dockerfiles or build scripts, ensure generated outputs stay in sync with `CreateMatrix` behavior.
- Keep base image definitions and derived image Dockerfiles aligned, since derived images build on the base images.
- Keep `README.md` and release documentation aligned with build outputs and product variants.
Loading
Loading