From 9147142eebc6d6d80d73ae7ff6e0eaf5481f9c07 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Wed, 5 Nov 2025 23:20:36 -0500 Subject: [PATCH 01/36] Remove some extensions not updated within the past year or not actively used --- .vscode/extensions.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 44b7e7b..3c676bc 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,10 +7,7 @@ "yzhang.markdown-all-in-one", "redhat.vscode-yaml", "mutantdino.resourcemonitor", - "zainchen.json", - "janisdd.vscode-edit-csv", "dotjoshjohnson.xml", - "IBM.output-colorizer", "davidanson.vscode-markdownlint" ] } From b4bd495612c4c56f6387b107349cfacf86d9b9bd Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Wed, 5 Nov 2025 23:21:31 -0500 Subject: [PATCH 02/36] Remove another old extension not actively updated --- .vscode/extensions.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3c676bc..94ff2a4 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,7 +6,6 @@ "pspester.pester-test", "yzhang.markdown-all-in-one", "redhat.vscode-yaml", - "mutantdino.resourcemonitor", "dotjoshjohnson.xml", "davidanson.vscode-markdownlint" ] From 5367bf8299d11f0a02fac5be845b3be1067bcc08 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Wed, 5 Nov 2025 23:22:27 -0500 Subject: [PATCH 03/36] Remove another old extension not actively maintained --- .vscode/extensions.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 94ff2a4..3be0b55 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,7 +6,6 @@ "pspester.pester-test", "yzhang.markdown-all-in-one", "redhat.vscode-yaml", - "dotjoshjohnson.xml", "davidanson.vscode-markdownlint" ] } From e0c06c6b071a01af7a7ff6ecc3b7260acc5e0b8a Mon Sep 17 00:00:00 2001 From: StepSecurity Bot Date: Wed, 31 Dec 2025 04:35:49 +0000 Subject: [PATCH 04/36] [StepSecurity] Apply security best practices Signed-off-by: StepSecurity Bot --- .github/dependabot.yml | 5 ++ .github/workflows/ci-cd-pipeline.yml | 12 +++- .github/workflows/dependency-review.yml | 27 +++++++++ .github/workflows/scorecards.yml | 81 +++++++++++++++++++++++++ .pre-commit-config.yaml | 10 +++ 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/scorecards.yml create mode 100644 .pre-commit-config.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8ca517d..163fee7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,8 @@ updates: directory: "/" # Location of package manifests schedule: interval: "weekly" + + - package-ecosystem: github-actions + directory: / + schedule: + interval: daily diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index bf2a95e..4978770 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -6,11 +6,19 @@ on: - main - develop +permissions: + contents: read + jobs: lint-and-test: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + with: + egress-policy: audit + + - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 # Install PSScriptAnalyzer - name: Install PSScriptAnalyzer @@ -34,7 +42,7 @@ jobs: # needs: lint-and-test # if: github.ref == 'refs/heads/main' # Only run for the main branch # steps: - # - uses: actions/checkout@v2 + # - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 # # # Package Scripts # - name: Package Scripts diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..83f47f1 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,27 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, +# PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + with: + egress-policy: audit + + - name: 'Checkout Repository' + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - name: 'Dependency Review' + uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 0000000..8bbb978 --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,81 @@ +# This workflow uses actions that are not certified by GitHub. They are provided +# by a third-party and are governed by separate terms of service, privacy +# policy, and support documentation. + +name: Scorecard supply-chain security +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '20 7 * * 2' + push: + branches: ["develop"] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + contents: read + actions: read + # To allow GraphQL ListCommits to work + issues: read + pull-requests: read + # To detect SAST tools + checks: read + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + with: + egress-policy: audit + + - name: "Checkout code" + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecards on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@45c373516f557556c15d420e3f5e0aa3d64366bc # v3.31.9 + with: + sarif_file: results.sarif diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..cba0860 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,10 @@ +repos: +- repo: https://github.com/gitleaks/gitleaks + rev: v8.16.3 + hooks: + - id: gitleaks +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: end-of-file-fixer + - id: trailing-whitespace From 99a019ef2fc24718aa8998c615df5a4c869d8411 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 04:36:45 +0000 Subject: [PATCH 05/36] Bump actions/upload-artifact from 4.6.2 to 6.0.0 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.2 to 6.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/ea165f8d65b6e75b540449e92b4886f43607fa02...b7c566a772e6b6bfb58ed0dc250532a479d7789f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8bbb978..733c5e9 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -68,7 +68,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: SARIF file path: results.sarif From 87d7cdb6c2166eb7efb8cab02e5be06181707b2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 04:36:55 +0000 Subject: [PATCH 06/36] Bump ossf/scorecard-action from 2.4.0 to 2.4.3 Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.4.0 to 2.4.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/62b2cac7ed8198b15735ed49ab1e5cf35480ba46...4eaacf0543bb3f2c246792bd56e8cdeffafb205a) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-version: 2.4.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8bbb978..2fff258 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -46,7 +46,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif From 3ef192920935ea69c7b85cc1f00e389789434dc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 19:36:46 +0000 Subject: [PATCH 07/36] Bump actions/checkout from 2.7.0 to 6.0.2 Bumps [actions/checkout](https://github.com/actions/checkout) from 2.7.0 to 6.0.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2.7.0...de0fac2e4500dabe0009e67214ff5f5447ce83dd) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci-cd-pipeline.yml | 4 ++-- .github/workflows/dependency-review.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index 4978770..627bff9 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -18,7 +18,7 @@ jobs: with: egress-policy: audit - - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Install PSScriptAnalyzer - name: Install PSScriptAnalyzer @@ -42,7 +42,7 @@ jobs: # needs: lint-and-test # if: github.ref == 'refs/heads/main' # Only run for the main branch # steps: - # - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 + # - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # # # Package Scripts # - name: Package Scripts diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 83f47f1..83386bb 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -22,6 +22,6 @@ jobs: egress-policy: audit - name: 'Checkout Repository' - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 'Dependency Review' uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8bbb978..ac50f2e 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -41,7 +41,7 @@ jobs: egress-policy: audit - name: "Checkout code" - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false From bd078d8db08ca5fa69f51104d0ad90ecf3acc8c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 21:17:29 +0000 Subject: [PATCH 08/36] Bump github/codeql-action from 3.31.9 to 4.32.0 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.31.9 to 4.32.0. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/45c373516f557556c15d420e3f5e0aa3d64366bc...b20883b0cd1f46c72ae0ba6d1090936928f9fa30) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: 4.32.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8bbb978..989159f 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -76,6 +76,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@45c373516f557556c15d420e3f5e0aa3d64366bc # v3.31.9 + uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 with: sarif_file: results.sarif From dae21a0129c8804b9650a6270162db05b37da616 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 21:17:36 +0000 Subject: [PATCH 09/36] Bump step-security/harden-runner from 2.14.0 to 2.14.1 Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.14.0 to 2.14.1. - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/20cf305ff2072d973412fa9b1e3a4f227bda3c76...e3f713f2d8f53843e71c69a996d56f51aa9adfb9) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.14.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci-cd-pipeline.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index 4978770..2e817b8 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -14,7 +14,7 @@ jobs: runs-on: windows-latest steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 with: egress-policy: audit diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 83f47f1..8749dea 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 with: egress-policy: audit diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 8bbb978..7bdc3e0 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 with: egress-policy: audit From c659abdcf5b8df7fc9b33e6bd58523c42748620b Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:04:48 -0500 Subject: [PATCH 10/36] Add README for PowerShell devcontainer setup This README provides an overview of the development container setup for PowerShell development, including configuration details, security controls, and usage instructions. --- .devcontainer/README.md | 172 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 .devcontainer/README.md diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..4f12099 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,172 @@ +# Development Container (`.devcontainer/`) + +## Overview + +This directory defines a reusable VS Code devcontainer for PowerShell development on a Wolfi base image. + +Primary goals: + +- Consistent PowerShell tooling across machines +- Fast onboarding with minimal host setup +- Reasonable hardening for development workloads without breaking day-to-day workflows + +## Current Defaults + +- Base image: `cgr.dev/chainguard/wolfi-base:latest` +- PowerShell version arg: `PS_VERSION=7.5.4` +- Core modules pinned to CI parity: + - `Pester=5.7.1` + - `PSScriptAnalyzer=1.24.0` +- AI tooling: enabled by default (`ENABLE_AI_TOOLS=true`) +- Runtime user: `vscode` (non-root) +- Container init enabled (`init: true`) +- Explicit workspace mount/folder: host repo is mounted at `/workspace` +- Musl compatibility env for Claude tooling: `USE_BUILTIN_RIPGREP=0` + +## Security and Reliability Controls + +The current config includes the following controls: + +- Non-root development user (`remoteUser: vscode`) +- UID/GID alignment enabled (`updateRemoteUserUID: true`) +- Runtime hardening via `runArgs`: + - `--security-opt=no-new-privileges` + - `--cap-drop=ALL` + - `--cap-add=DAC_OVERRIDE` +- Read-only bind mount of `.devcontainer` into the container at `/workspace/.devcontainer` + - This reduces risk of in-container tampering with `devcontainer.json` / `Dockerfile` before a rebuild. +- Minimal init process enabled (`init: true`) to improve PID 1 signal handling and child process reaping +- Telemetry opt-out environment variables for .NET and PowerShell +- PowerShell tarball SHA-256 verification before extraction +- Strict shell behavior (`set -euo pipefail`) in the optional AI tooling setup block +- Build context locked down via `.dockerignore` +- OCI image labels for title/description/source/license/revision/created metadata +- Optional Claude sandbox prerequisites included when AI tooling is enabled (`bubblewrap`, `socat`) +- Git `safe.directory` pre-registration for `/workspace` to reduce Podman ownership-warning churn during attach +- Capability model rationale: + - `--cap-drop=ALL` remains the baseline. + - `DAC_OVERRIDE` is explicitly re-added because VS Code server install/setup in this Podman flow may execute through a root session that must create paths under `/vscode/vscode-server`. + - This avoids startup permission failures without host-side permission mutation scripts. + +Guardrails: + +- Do not add Linux capabilities beyond `DAC_OVERRIDE` unless explicitly required. +- Do not add `SYS_ADMIN` for this devcontainer profile. + +## Post-Create Validation + +`postCreateCommand` imports required versions and fails if version requirements are not met. It then prints versions for: + +- `pwsh` +- `Pester` +- `PSScriptAnalyzer` + +## Workspace and Persistence Model + +- Workspace path inside container is `/workspace` (set explicitly in `devcontainer.json`). +- `.devcontainer` is mounted read-only inside the container to help protect host-side devcontainer config from in-container modification. +- No repo-managed persistent dev volumes are configured in `devcontainer.json`. +- VS Code Dev Containers may mount a shared external `vscode` volume at `/vscode` for VS Code server and extension cache data. +- Rebuilds still reset most runtime state (for example, shell history/tool config) unless you add additional mounts. + +## Files in This Directory + +- `devcontainer.json`: Devcontainer runtime settings, hardening `runArgs`, env vars, post-create validation +- `Dockerfile`: Image build logic and tooling installation +- `.dockerignore`: Restricts build context to devcontainer files +- `README.md`: This document + +## Build Arguments + +Supported Docker build args: + +- `PS_VERSION` (default: `7.5.4`) +- `PESTER_VERSION` (default: `5.7.1`) +- `PSSA_VERSION` (default: `1.24.0`) +- `ENABLE_AI_TOOLS` (default: `true`) +- `TARGETARCH` (must be provided by BuildKit/devcontainer tooling) +- `BUILDKIT_INLINE_CACHE` (default: `1`, consumed to avoid noisy build warnings) +- `IMAGE_TITLE` +- `IMAGE_DESCRIPTION` +- `IMAGE_SOURCE` +- `IMAGE_LICENSES` +- `VCS_REF` +- `BUILD_DATE` + +Notes: + +- `TARGETARCH` has no fallback default by design. Builds fail fast if it is missing. +- The current image policy intentionally tracks latest Wolfi base and latest OS package versions at build time. +- PowerShell module versions are pinned to the same versions used in CI for local/CI parity. + +## Podman + VS Code Setup + +This repo is tested with Podman on Linux and Windows+WSL. + +Minimum VS Code setting: + +```json +{ + "dev.containers.dockerPath": "podman" +} +``` + +Optional if you use compose-based devcontainers: + +```json +{ + "dev.containers.dockerComposePath": "podman-compose" +} +``` + +Roadmap: Evaluate VS Code volume-based workspace workflow (Clone in Volume) as a future improvement for performance and reduced host-to-container exposure. + +## AI Tooling (Default On) + +AI tooling is enabled by default (`ENABLE_AI_TOOLS=true`). For constrained environments, you can opt out by setting `ENABLE_AI_TOOLS=false` in a local devcontainer override. + +When enabled, the image installs: + +- Wolfi Node runtime (`nodejs-22`, `npm`) and package-management install flow +- Codex CLI via npm (`@openai/codex@latest`) with user-local npm prefix under `/home/vscode/.local` +- Claude Code via native installer (`curl -fsSL https://claude.ai/install.sh | bash`) +- Claude sandbox prerequisites on Linux/WSL (`bubblewrap`, `socat`) +- additional workflow tools (`delta`, `fzf`, `gh`) +- common CLI helpers (`ripgrep`, `fd`, `jq`, `yq`, `patch`, `diffutils`, `tree`, etc.) + +Wolfi/musl notes: + +- `USE_BUILTIN_RIPGREP=0` is set in `containerEnv` for Claude compatibility on musl-based distributions. +- Required runtime libraries are present in the base image (`libgcc`, `libstdc++`) and `ripgrep` is installed in the AI tooling path. + +Sandboxing notes: + +- This profile is optimized for strong outer container isolation plus Claude nested sandbox support. +- Codex nested Docker firewall sandboxing (`NET_ADMIN`/`NET_RAW` + allowlists) is intentionally not enabled in this default hardened profile. + +This path can be disabled for constrained environments and is not required for PowerShell module development. + +## Expected Log Noise (Can Be Ignored) + +You may still see these warnings from VS Code/Podman internals during container startup: + +- `Ignoring option 'skip-requirements-check' ...` +- `Error: AttachConsole failed` (transient Windows ConPTY/node-pty noise; non-fatal when container startup and attach succeed) +- `safe.directory: Failed to get host owner ... powershell.exe ENOENT` (host owner probe noise on some Windows/WSL Podman paths; non-fatal when attach succeeds) + +These come from generated helper images or VS Code server internals, not from functional issues in this repo's devcontainer configuration. + +## Usage + +1. Open the repository in VS Code. +2. Run `Dev Containers: Reopen in Container`. +3. Wait for the first build to complete. +4. Confirm post-create output includes `pwsh`, `Pester`, and `PSScriptAnalyzer` version lines. + +## Non-Goals + +This devcontainer is for development convenience and consistency. It is not intended as: + +- A production runtime image +- A hardened service container profile +- A published, immutable release image From e818ba6696db4755e2fb346e8cbfc6f239087a19 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:05:15 -0500 Subject: [PATCH 11/36] Add .dockerignore to exclude all except Dockerfile --- .devcontainer/.dockerignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .devcontainer/.dockerignore diff --git a/.devcontainer/.dockerignore b/.devcontainer/.dockerignore new file mode 100644 index 0000000..d864cae --- /dev/null +++ b/.devcontainer/.dockerignore @@ -0,0 +1,3 @@ +* +!Dockerfile +!.dockerignore From 3cf42d0976131ed13f0367746a0b78efaa7284cb Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:05:45 -0500 Subject: [PATCH 12/36] Add PowerShell Dev Container configuration --- .devcontainer/devcontainer.json | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..7b14c83 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json", + "name": "PowerShell Dev Container (Wolfi)", + "build": { + "dockerfile": "Dockerfile", + "args": { + "PS_VERSION": "7.5.4", + "PESTER_VERSION": "5.7.1", + "PSSA_VERSION": "1.24.0", + "ENABLE_AI_TOOLS": "true" + } + }, + "remoteUser": "vscode", + "init": true, + "updateRemoteUserUID": true, + "mounts": [ + "source=${localWorkspaceFolder}/.devcontainer,target=/workspace/.devcontainer,type=bind,readonly" + ], + "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind", + "workspaceFolder": "/workspace", + "runArgs": [ + "--security-opt=no-new-privileges", + "--cap-drop=ALL", + "--cap-add=DAC_OVERRIDE" + ], + "containerEnv": { + "DOTNET_CLI_TELEMETRY_OPTOUT": "1", + "POWERSHELL_TELEMETRY_OPTOUT": "1", + "USE_BUILTIN_RIPGREP": "0" + }, + "postCreateCommand": "pwsh -NoProfile -Command '$ErrorActionPreference = \"Stop\"; $requiredPester = [Version]\"5.7.1\"; $requiredPssa = [Version]\"1.24.0\"; Import-Module Pester -RequiredVersion $requiredPester -Force; Import-Module PSScriptAnalyzer -RequiredVersion $requiredPssa -Force; $pesterVersion = (Get-Module -Name Pester).Version; $pssaVersion = (Get-Module -Name PSScriptAnalyzer).Version; if ($pesterVersion -ne $requiredPester) { throw \"Expected Pester $requiredPester but found $pesterVersion\" }; if ($pssaVersion -ne $requiredPssa) { throw \"Expected PSScriptAnalyzer $requiredPssa but found $pssaVersion\" }; Write-Host (\"pwsh: \" + $PSVersionTable.PSVersion); Write-Host (\"Pester: \" + $pesterVersion); Write-Host (\"PSScriptAnalyzer: \" + $pssaVersion)'", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "pwsh" + } + } + } +} From d8e0f2f676154c83192d8a60a0f07ca6978bda20 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:06:26 -0500 Subject: [PATCH 13/36] Add Dockerfile for PowerShell development container --- .devcontainer/Dockerfile | 149 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 .devcontainer/Dockerfile diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..cad52b7 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,149 @@ +# syntax=docker/dockerfile:1 +FROM cgr.dev/chainguard/wolfi-base:latest + +ARG PS_VERSION=7.5.4 +ARG PESTER_VERSION=5.7.1 +ARG PSSA_VERSION=1.24.0 +ARG TARGETARCH +ARG ENABLE_AI_TOOLS=true +ARG BUILDKIT_INLINE_CACHE=1 +ARG IMAGE_TITLE="PowerShell Dev Container" +ARG IMAGE_DESCRIPTION="Wolfi-based PowerShell development container" +ARG IMAGE_SOURCE="https://github.com/thetechgy/ArchiTechLabs-Script-Hub" +ARG IMAGE_LICENSES="MIT" +ARG VCS_REF="unknown" +ARG BUILD_DATE="unknown" + +LABEL org.opencontainers.image.title="${IMAGE_TITLE}" \ + org.opencontainers.image.description="${IMAGE_DESCRIPTION}" \ + org.opencontainers.image.source="${IMAGE_SOURCE}" \ + org.opencontainers.image.licenses="${IMAGE_LICENSES}" \ + org.opencontainers.image.revision="${VCS_REF}" \ + org.opencontainers.image.created="${BUILD_DATE}" + +# ----------------------------- +# Base OS packages (always needed) +# ----------------------------- +RUN apk add --no-cache \ + bash \ + ca-certificates \ + curl \ + git \ + gnupg-gpgconf \ + openssh-client \ + icu-libs \ + libstdc++ \ + libgcc + +# ----------------------------- +# Install PowerShell +# ----------------------------- +RUN : "${TARGETARCH:?TARGETARCH must be set by BuildKit}" \ + && case "${TARGETARCH}" in \ + amd64) PS_ARCH="x64" ;; \ + arm64) PS_ARCH="arm64" ;; \ + *) echo "Unsupported TARGETARCH=${TARGETARCH}" && exit 1 ;; \ + esac \ + && PS_TARBALL="powershell-${PS_VERSION}-linux-${PS_ARCH}.tar.gz" \ + && mkdir -p "/opt/microsoft/powershell/${PS_VERSION}" \ + && curl -fsSL -o "/tmp/${PS_TARBALL}" \ + "https://github.com/PowerShell/PowerShell/releases/download/v${PS_VERSION}/${PS_TARBALL}" \ + && curl -fsSL -o /tmp/hashes.sha256 \ + "https://github.com/PowerShell/PowerShell/releases/download/v${PS_VERSION}/hashes.sha256" \ + && PS_EXPECTED_SHA256="" \ + && while IFS= read -r checksum_line; do \ + case "${checksum_line}" in \ + *"${PS_TARBALL}"*) PS_EXPECTED_SHA256="${checksum_line%% *}"; break ;; \ + esac; \ + done < /tmp/hashes.sha256 \ + && [ -n "${PS_EXPECTED_SHA256}" ] \ + && PS_EXPECTED_SHA256="$(printf '%s' "${PS_EXPECTED_SHA256}" | tr '[:upper:]' '[:lower:]')" \ + && set -- $(sha256sum "/tmp/${PS_TARBALL}") \ + && PS_ACTUAL_SHA256="$1" \ + && if [ "${PS_ACTUAL_SHA256}" != "${PS_EXPECTED_SHA256}" ]; then \ + echo "Checksum mismatch for ${PS_TARBALL}" >&2; \ + echo "Expected: ${PS_EXPECTED_SHA256}" >&2; \ + echo "Actual: ${PS_ACTUAL_SHA256}" >&2; \ + exit 1; \ + fi \ + && tar -xzf "/tmp/${PS_TARBALL}" -C "/opt/microsoft/powershell/${PS_VERSION}" \ + && rm -f "/tmp/${PS_TARBALL}" /tmp/hashes.sha256 \ + && chmod 755 "/opt/microsoft/powershell/${PS_VERSION}/pwsh" \ + && chmod -R a+rX "/opt/microsoft/powershell/${PS_VERSION}" \ + && mkdir -p /usr/local/bin \ + && ln -sf "/opt/microsoft/powershell/${PS_VERSION}/pwsh" /usr/local/bin/pwsh \ + && ln -sf "/opt/microsoft/powershell/${PS_VERSION}/pwsh" /usr/bin/pwsh \ + && pwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion.ToString()' + +# ----------------------------- +# PowerShell tooling (always needed) +# ----------------------------- +RUN pwsh -NoLogo -NoProfile -Command "\ + Set-PSRepository -Name PSGallery -InstallationPolicy Trusted; \ + Install-Module Pester -RequiredVersion ${PESTER_VERSION} -Scope AllUsers -Force -AllowClobber; \ + Install-Module PSScriptAnalyzer -RequiredVersion ${PSSA_VERSION} -Scope AllUsers -Force -AllowClobber; \ + Import-Module Pester -RequiredVersion ${PESTER_VERSION} -Force; \ + Import-Module PSScriptAnalyzer -RequiredVersion ${PSSA_VERSION} -Force; \ + " + +# ----------------------------- +# Non-root user for devcontainers +# ----------------------------- +RUN adduser -D -u 1000 vscode \ + && mkdir -p /home/vscode \ + && chown -R vscode:vscode /home/vscode + +# Avoid git dubious-ownership warnings for the fixed devcontainer workspace path. +RUN git config --system --add safe.directory /workspace + +# ----------------------------- +# AI tooling + CLIs (optional) +# ----------------------------- +RUN if [ "${ENABLE_AI_TOOLS}" = "true" ]; then \ + echo 'Installing AI assist tooling + Node + Codex + Claude...' && \ + apk add --no-cache \ + nodejs-22 \ + npm \ + bubblewrap \ + socat \ + procps \ + gh \ + delta \ + fzf \ + ripgrep \ + fd \ + jq \ + yq \ + patch \ + diffutils \ + sed \ + gawk \ + coreutils \ + findutils \ + tree \ + gzip \ + unzip \ + xz \ + && mkdir -p /etc/profile.d \ + && printf '%s\n' \ + 'export PATH="$HOME/.local/bin:$PATH"' \ + > /etc/profile.d/00-devcontainer-paths.sh \ + && su -s /bin/bash vscode -c ' \ + set -euo pipefail; \ + export PATH="$HOME/.local/bin:$PATH"; \ + mkdir -p "$HOME/.local" "$HOME/.npm"; \ + npm config set prefix "$HOME/.local"; \ + npm config set cache "$HOME/.npm"; \ + node --version; npm --version; \ + npm i -g @openai/codex@latest; \ + codex --version || true; \ + mkdir -p "$HOME/.local/bin"; \ + curl -fsSL https://claude.ai/install.sh | bash; \ + command -v claude >/dev/null 2>&1 && claude --version || true; \ + ' \ + ; else \ + echo 'AI tooling disabled (ENABLE_AI_TOOLS=false)'; \ + fi + +USER vscode +WORKDIR /workspaces From 27caf28214c42ba8a4379d900125192d425fe1db Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:09:22 -0500 Subject: [PATCH 14/36] Add conservative allowlist and block rules --- .codex/rules/default.rules | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .codex/rules/default.rules diff --git a/.codex/rules/default.rules b/.codex/rules/default.rules new file mode 100644 index 0000000..c7e5e94 --- /dev/null +++ b/.codex/rules/default.rules @@ -0,0 +1,26 @@ +# Conservative allowlist for low-risk, high-frequency commands. +prefix_rule(pattern=["git", "status"], decision="allow") +prefix_rule(pattern=["git", "diff"], decision="allow") +prefix_rule(pattern=["git", "log"], decision="allow") +prefix_rule(pattern=["git", "show"], decision="allow") +prefix_rule(pattern=["git", "rev-parse"], decision="allow") +prefix_rule(pattern=["git", "branch", "--show-current"], decision="allow") +prefix_rule(pattern=["git", "ls-files"], decision="allow") + +# Shared repo validation workflow. +prefix_rule(pattern=["pwsh", "-NoProfile", "-File", ".\\Invoke-RepoChecks.ps1"], decision="allow") +prefix_rule(pattern=["pwsh", "-NoProfile", "-File", "./Invoke-RepoChecks.ps1"], decision="allow") +prefix_rule(pattern=["pwsh", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ".\\Invoke-RepoChecks.ps1"], decision="allow") +prefix_rule(pattern=["powershell", "-NoProfile", "-File", ".\\Invoke-RepoChecks.ps1"], decision="allow") +prefix_rule(pattern=["powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", ".\\Invoke-RepoChecks.ps1"], decision="allow") + +# Direct analyzer/test commandlets in both PowerShell 7 and Windows PowerShell. +prefix_rule(pattern=["pwsh", "-NoProfile", "-Command", "Invoke-ScriptAnalyzer"], decision="allow") +prefix_rule(pattern=["powershell", "-NoProfile", "-Command", "Invoke-ScriptAnalyzer"], decision="allow") +prefix_rule(pattern=["pwsh", "-NoProfile", "-Command", "Invoke-Pester"], decision="allow") +prefix_rule(pattern=["powershell", "-NoProfile", "-Command", "Invoke-Pester"], decision="allow") + +# Hard blocks for destructive patterns that should never auto-run. +prefix_rule(pattern=["git", "reset", "--hard"], decision="forbidden") +prefix_rule(pattern=["git", "clean", "-fdx"], decision="forbidden") +prefix_rule(pattern=["rm", "-rf"], decision="forbidden") From ffb2f5ee5065ffb9cc8faa09ebb1ace3f32d1d0d Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:09:46 -0500 Subject: [PATCH 15/36] Create .codex/config.toml with initial settings Add configuration settings for Codex model and profiles. --- .codex/config.toml | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .codex/config.toml diff --git a/.codex/config.toml b/.codex/config.toml new file mode 100644 index 0000000..9417db3 --- /dev/null +++ b/.codex/config.toml @@ -0,0 +1,45 @@ +model = "gpt-5.3-codex" +model_reasoning_effort = "high" +model_verbosity = "high" + +approval_policy = "untrusted" +sandbox_mode = "workspace-write" +allow_login_shell = false + +cli_auth_credentials_store = "auto" +web_search = "live" + +[features] +multi_agent = true + +[agents] +max_threads = 4 +max_depth = 1 + +[shell_environment_policy] +inherit = "core" +ignore_default_excludes = false + +[sandbox_workspace_write] +network_access = false + +[history] +persistence = "save-all" +max_bytes = 5242880 + +# Profiles are currently experimental in Codex docs. +[profiles.ci_safe] +model = "gpt-5.3-codex" +model_reasoning_effort = "high" +model_verbosity = "medium" +approval_policy = "never" +sandbox_mode = "read-only" +allow_login_shell = false +web_search = "disabled" + +[profiles.ci_safe.shell_environment_policy] +inherit = "core" +ignore_default_excludes = false + +[profiles.ci_safe.history] +persistence = "none" From 15d94c2cbe206e31608189d68a48fdbebe6cc043 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:10:09 -0500 Subject: [PATCH 16/36] Add README for Codex policy notes Document the strict Codex approval policy for workspace safety, including intent, limitations, and expected commands. --- .codex/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .codex/README.md diff --git a/.codex/README.md b/.codex/README.md new file mode 100644 index 0000000..b7a513a --- /dev/null +++ b/.codex/README.md @@ -0,0 +1,33 @@ +# Codex Policy Notes (Strict Workspace Safety) + +This repository uses a strict Codex approval policy for cross-platform use on: + +- Windows 11 (`powershell` / `pwsh`) +- Devcontainer environments + +## Intent + +- Keep `approval_policy = "untrusted"` and `sandbox_mode = "workspace-write"`. +- Keep network access disabled in workspace sandbox (`network_access = false`). +- Use a narrow allowlist in `.codex/rules/default.rules` for expected low-risk workflows. + +## Important Limitation + +`allow` rules are convenience controls for command prefixes. They are **not** a workspace-path guard and do not prove a command is read-only. + +Because of that, this repo does **not** allow broad command prefixes such as: + +- generic shell wrappers (for example `pwsh -Command ...`, `bash -lc ...`) +- broad read command families (`ls`, `cat`, `find`, etc.) + +Extra read commands may still require approval by design. + +## Expected No-Prompt Commands + +- Selected git read operations (`status`, `diff`, `log`, `show`, `rev-parse`, `branch --show-current`, `ls-files`) +- Repo check script (`Invoke-RepoChecks.ps1`) in `pwsh` and `powershell` +- Direct analyzer/test commandlets: + - `Invoke-ScriptAnalyzer` + - `Invoke-Pester` + +All other commands are intentionally reviewed case-by-case. From ec58b509bdd8653688bfd35124018711ed3e9d08 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:11:43 -0500 Subject: [PATCH 17/36] Revise VS Code extension recommendations Updated recommended extensions for VS Code. --- .vscode/extensions.json | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3be0b55..ee60c27 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,11 +1,13 @@ { - "recommendations": [ - "ms-vscode.powershell", - "eamodio.gitlens", - "editorconfig.editorconfig", - "pspester.pester-test", - "yzhang.markdown-all-in-one", - "redhat.vscode-yaml", - "davidanson.vscode-markdownlint" - ] + "recommendations": [ + "ms-vscode.PowerShell", + "pspester.pester-test", + "github.vscode-github-actions", + "GitHub.vscode-pull-request-github", + "EditorConfig.EditorConfig", + "redhat.vscode-yaml", + "DavidAnson.vscode-markdownlint", + "streetsidesoftware.code-spell-checker", + "PKief.material-icon-theme" + ] } From 2a9e7edfc29c8be195ec824a699323c0acdedbc0 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:14:46 -0500 Subject: [PATCH 18/36] Update VS Code settings with new configurations Removed several editor settings and added new configurations for icon theme, AI features, and Git blame settings. --- .vscode/settings.json | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 465f1bc..0bd8ee8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,19 +1,15 @@ { - "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true, - "files.eol": "\n", - "editor.tabSize": 4, - "editor.insertSpaces": true, - "editor.formatOnSave": true, - "powershell.codeFormatting.preset": "OTBS", - "powershell.codeFormatting.useCorrectCasing": true, + "workbench.iconTheme": "material-icon-theme", + "chat.disableAIFeatures": true, + "git.blame.editorDecoration.enabled": true, + "git.blame.statusBarItem.enabled": true, "powershell.scriptAnalysis.enable": true, "powershell.scriptAnalysis.settingsPath": "./PSScriptAnalyzerSettings.psd1", - "extensions.ignoreRecommendations": false, - "terminal.integrated.defaultProfile.windows": "PowerShell 7", - "terminal.integrated.profiles.windows": { - "PowerShell 7": { - "path": "C:\\Program Files\\PowerShell\\7\\pwsh.exe" - } + // cSpell: keep Spell Checker available, stop reporting into Problems + "cSpell.diagnosticLevel": "Hint", + "search.exclude": { + "**/.git/**": true, + "**/Output/**": true, + "**/Logs/**": true } } From ad042570912a133efe4c8611745993e08bfd91d1 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:15:14 -0500 Subject: [PATCH 19/36] Update .editorconfig with line length settings --- .editorconfig | 71 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/.editorconfig b/.editorconfig index 2711ac1..5a952c7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,18 +1,81 @@ root = true +# ------------------------------------------------------- +# Defaults +# ------------------------------------------------------- [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true - -[*.ps1] indent_style = space indent_size = 4 +max_line_length = 120 + +# ------------------------------------------------------- +# PowerShell source files (code) +# ------------------------------------------------------- +[*.{ps1,psm1}] +indent_size = 4 +max_line_length = 120 + +# Pester test files (allow longer assertions/Describe blocks) +[**/*.[Tt]ests.ps1] +indent_size = 4 +max_line_length = 140 +# PowerShell manifests / data / session config (still PowerShell syntax) +# Best practice: keep consistent with PowerShell code indentation to reduce churn. +[*.{psd1,pssc,psrc}] +indent_size = 4 +max_line_length = 120 + +[PSScriptAnalyzerSettings.psd1] +indent_size = 4 + +# ------------------------------------------------------- +# Markdown +# ------------------------------------------------------- [*.md] +indent_size = 2 trim_trailing_whitespace = false +max_line_length = off -[*.json] -indent_style = space +# ------------------------------------------------------- +# JSON / JSONC (Logic Apps, configs) +# ------------------------------------------------------- +[*.{json,jsonc}] +indent_size = 2 +max_line_length = off + +# ------------------------------------------------------- +# YAML (GitHub Actions, Dependabot, issue templates) +# ------------------------------------------------------- +[*.{yml,yaml}] +indent_size = 2 +max_line_length = off + +# ------------------------------------------------------- +# XML +# ------------------------------------------------------- +[*.{xml,nuspec,ps1xml,cdxml}] indent_size = 2 +max_line_length = 120 + +# ------------------------------------------------------- +# Shell scripts +# ------------------------------------------------------- +[*.sh] +indent_size = 2 + +# ------------------------------------------------------- +# Windows batch scripts +# ------------------------------------------------------- +[*.{cmd,bat}] +end_of_line = crlf + +# ------------------------------------------------------- +# Repo meta / Git config +# ------------------------------------------------------- +[{.gitattributes,.gitignore,LICENSE}] +max_line_length = off From f321d3f303c8f3e5cddca1d13c39808f9f94bdba Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:15:30 -0500 Subject: [PATCH 20/36] Update .gitattributes for text and binary files --- .gitattributes | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/.gitattributes b/.gitattributes index 669db0d..41cb633 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,22 @@ -* text=auto -*.ps1 text eol=lf -*.md text -*.log binary -*.csv text -*.json text -*.zip binary +# Normalize all text to LF +* text=auto eol=lf + +# Windows batch scripts +*.cmd text eol=crlf +*.bat text eol=crlf + +# Common binaries +*.zip binary +*.7z binary +*.tar binary +*.gz binary +*.rar binary +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.pdf binary + +# SVG is text-based +*.svg text eol=lf From d6ef056995db64a20902ce988d345a059710f2e1 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:15:49 -0500 Subject: [PATCH 21/36] Delete .pre-commit-config.yaml --- .pre-commit-config.yaml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index cba0860..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -repos: -- repo: https://github.com/gitleaks/gitleaks - rev: v8.16.3 - hooks: - - id: gitleaks -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 - hooks: - - id: end-of-file-fixer - - id: trailing-whitespace From bff98336b3dc1cf3926daf72bb089204a7397b25 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:16:43 -0500 Subject: [PATCH 22/36] Enhance .gitignore with additional patterns Expanded .gitignore to include various OS-specific files, VS Code configurations, PowerShell artifacts, test outputs, coverage files, and temporary files. --- .gitignore | 95 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 30f6733..308bc0e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,89 @@ -**/Output/**/*.log -**/Output/**/*.csv -**/Output/**/*.json -**/Output/**/*.txt -**/Logs/** -*.log +# ---------------------------- +# OS Specific (Windows) +# ---------------------------- +Thumbs.db +Desktop.ini +# ---------------------------- +# VS Code (track team config only) +# ---------------------------- .vscode/* !.vscode/settings.json !.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json -*.zip -artifacts/ -build/ +.vscode-server/ +*.code-workspace.user -Thumbs.db -.DS_Store -*.ps1xml +# ---------------------------- +# PowerShell +# ---------------------------- +# PSScriptAnalyzer user overrides +PSScriptAnalyzerSettings.psd1.user + +# Transcripts +PowerShell_transcript*.txt + +# Extension/cache byproducts +*.ps1.cache +*.psd1.cache +*.psm1.cache + +# ---------------------------- +# Pester / Test output +# ---------------------------- +**/TestResults/ +testResults.xml +*.TestResults.xml +*.trx +*.nunit.xml +*.junit.xml + +# Coverage outputs +coverage.xml +**/coverage*/ +codecoverage*.xml +*.cobertura.xml + +# Pester cache +.pester/ + +# ---------------------------- +# Build / artifact output +# ---------------------------- +Output/ +Logs/ +Reports/ + +# ---------------------------- +# Logs (generic) +# ---------------------------- +*.log + +# ---------------------------- +# Secrets & Credentials (local-only) +# ---------------------------- +.env +.env.* +.env.local +.env.*.local + +*.secrets.json +*.private.json +*-credentials.json +*.azureauth + +sp-*.json +ServicePrincipal.json + +# ---------------------------- +# Temporary & editor junk +# ---------------------------- +*.tmp +*.temp +*.bak +*.swp +*~ +*.orig +*.rej From ec1c791629857191a58980bee64ca2476cb1bf9c Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:17:04 -0500 Subject: [PATCH 23/36] Add markdownlint configuration file --- .markdownlint.jsonc | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .markdownlint.jsonc diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 0000000..99ca0bf --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,10 @@ +{ + // Keep defaults on; selectively relax rules that commonly create noise. + "default": true, + // Line length: off (consistent with .editorconfig for Markdown) + "MD013": false, + // Inline HTML: allow (badges, tables,
, details/summary) + "MD033": false, + // First line heading: allow (badges/front-matter/title blocks) + "MD041": false +} From bc60ade31511505fa339d71044f6bcc9b3bc04fa Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:20:16 -0500 Subject: [PATCH 24/36] Add PSScriptAnalyzerSettings for code analysis --- PSScriptAnalyzerSettings.psd1 | 94 +++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 PSScriptAnalyzerSettings.psd1 diff --git a/PSScriptAnalyzerSettings.psd1 b/PSScriptAnalyzerSettings.psd1 new file mode 100644 index 0000000..28b1942 --- /dev/null +++ b/PSScriptAnalyzerSettings.psd1 @@ -0,0 +1,94 @@ +@{ + # Keep signal high for a shared repo. Info-level findings tend to create noise. + Severity = @('Error', 'Warning') + + # Rules excluded intentionally due to common false-positives or known analyzer issues. + ExcludeRules = @( + # Frequently noisy with splatting, scriptblocks, and dynamic parameter patterns. + 'PSReviewUnusedParameter' + + # Known to be unstable/buggy in some analyzer versions/patterns. + 'AvoidReservedCharInCmdlet' + ) + + Rules = @{ + + # --------------------------------------------------------------------- + # Compatibility (PS 5.1 + PS 7) + # --------------------------------------------------------------------- + PSUseCompatibleSyntax = @{ + Enable = $true + # Enforces syntax that works in BOTH Windows PowerShell 5.1 and PowerShell 7+. + TargetVersions = @('5.1', '7.0') + } + + # --------------------------------------------------------------------- + # Authoring / maintainability + # --------------------------------------------------------------------- + PSUseApprovedVerbs = @{ + Enable = $true + } + + PSProvideCommentHelp = @{ + Enable = $true + # Public surface should be documented; internal helpers are often too noisy to enforce globally. + ExportedOnly = $true + } + + PSUseShouldProcessForStateChangingFunctions = @{ + Enable = $true + } + + PSAvoidGlobalVars = @{ + Enable = $true + } + + # --------------------------------------------------------------------- + # Security / unsafe patterns + # --------------------------------------------------------------------- + PSAvoidUsingInvokeExpression = @{ + Enable = $true + } + + PSAvoidUsingConvertToSecureStringWithPlainText = @{ + Enable = $true + } + + PSAvoidUsingPlainTextForPassword = @{ + Enable = $true + } + + # --------------------------------------------------------------------- + # Team-consistent readability (minimal, to reduce diff churn) + # --------------------------------------------------------------------- + PSAvoidUsingCmdletAliases = @{ + Enable = $true + } + + PSAvoidUsingWriteHost = @{ + Enable = $true + } + + PSUseConsistentIndentation = @{ + Enable = $true + IndentationSize = 4 + Kind = 'space' + } + + PSPlaceOpenBrace = @{ + Enable = $true + OnSameLine = $true + IgnoreOneLineBlock = $true + } + + PSPlaceCloseBrace = @{ + Enable = $true + NoEmptyLineBefore = $true + IgnoreOneLineBlock = $true + } + + # Intentionally NOT forcing these (higher churn / opinionated style policing): + PSUseConsistentWhitespace = @{ Enable = $false } + PSAlignAssignmentStatement = @{ Enable = $false } + } +} From 8da970374ba50121e54727aa3cf0a5ef9356cb03 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:20:50 -0500 Subject: [PATCH 25/36] Configure Dependabot for GitHub Actions updates Added GitHub Actions configuration for Dependabot updates, specifying schedule, labels, and grouping for minor, patch, and major updates. --- .github/dependabot.yml | 46 ++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 163fee7..0d5ee92 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,16 +1,40 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file - version: 2 + updates: - - package-ecosystem: "nuget" # See documentation for possible values - directory: "/" # Location of package manifests + # ------------------------------------------------------------ + # GitHub Actions (workflows + composite actions) + # ------------------------------------------------------------ + - package-ecosystem: "github-actions" + directory: "/" + target-branch: "develop" schedule: interval: "weekly" + day: "monday" + time: "09:00" + timezone: "America/New_York" + open-pull-requests-limit: 2 + rebase-strategy: "auto" - - package-ecosystem: github-actions - directory: / - schedule: - interval: daily + # Keep PRs easy to route/triage + labels: + - "dependencies" + - "github-actions" + + # Reduce PR spam by grouping updates + groups: + github-actions-minor-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + github-actions-major: + patterns: + - "*" + update-types: + - "major" + + # Make PRs consistent and readable + commit-message: + prefix: "chore" + include: "scope" From f8f7079a35a5ee4f31a5af371179183d9743ed04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:21:57 +0000 Subject: [PATCH 26/36] chore(deps): bump the github-actions-minor-patch group with 3 updates Bumps the github-actions-minor-patch group with 3 updates: [step-security/harden-runner](https://github.com/step-security/harden-runner), [actions/dependency-review-action](https://github.com/actions/dependency-review-action) and [github/codeql-action](https://github.com/github/codeql-action). Updates `step-security/harden-runner` from 2.14.1 to 2.15.1 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/e3f713f2d8f53843e71c69a996d56f51aa9adfb9...58077d3c7e43986b6b15fba718e8ea69e387dfcc) Updates `actions/dependency-review-action` from 4.8.2 to 4.9.0 - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261...2031cfc080254a8a887f58cffee85186f0e49e48) Updates `github/codeql-action` from 4.32.0 to 4.32.6 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/b20883b0cd1f46c72ae0ba6d1090936928f9fa30...0d579ffd059c29b07949a3cce3983f0780820c98) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.15.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-minor-patch - dependency-name: actions/dependency-review-action dependency-version: 4.9.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-minor-patch - dependency-name: github/codeql-action dependency-version: 4.32.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-minor-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci-cd-pipeline.yml | 2 +- .github/workflows/dependency-review.yml | 4 ++-- .github/workflows/scorecards.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index 66f5f9b..7a0335f 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -14,7 +14,7 @@ jobs: runs-on: windows-latest steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 with: egress-policy: audit diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 690337a..7cdcdfc 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -17,11 +17,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 with: egress-policy: audit - name: 'Checkout Repository' uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 'Dependency Review' - uses: actions/dependency-review-action@3c4e3dcb1aa7874d2c16be7d79418e9b7efd6261 # v4.8.2 + uses: actions/dependency-review-action@2031cfc080254a8a887f58cffee85186f0e49e48 # v4.9.0 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 188ca14..82b58d9 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 with: egress-policy: audit @@ -76,6 +76,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0 + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: sarif_file: results.sarif From c768c3003d19d3b4074e3ae72c0b6f083fd532ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:22:01 +0000 Subject: [PATCH 27/36] chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 188ca14..8654996 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -68,7 +68,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: SARIF file path: results.sarif From 98ef54348edc50d8b9d8bb9581aa4d1b914dcd2a Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:22:15 -0500 Subject: [PATCH 28/36] Create CODEOWNERS file for repository management Add CODEOWNERS file to specify repository owners. --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..ff8b4d1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# GitHub configuration (workflows, templates, dependabot, policies) + +.github/ @thetechgy From f2f94e1a9d3e45102df356cd7b1186c689c07bbe Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:27:08 -0500 Subject: [PATCH 29/36] Enhance CI/CD pipeline with testing and analysis Updated CI/CD pipeline to include PSScriptAnalyzer and Pester testing for both PowerShell 5.1 and PowerShell 7. Added conditions for running on pull requests and pushes to specific branches. --- .github/workflows/ci-cd-pipeline.yml | 274 +++++++++++++++++++++++---- 1 file changed, 238 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml index 66f5f9b..8830b14 100644 --- a/.github/workflows/ci-cd-pipeline.yml +++ b/.github/workflows/ci-cd-pipeline.yml @@ -20,43 +20,245 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - # Install PSScriptAnalyzer + name: CI + +on: + pull_request: + branches: [develop, main] + paths-ignore: + - "docs/**" + - "**/*.md" + - ".vscode/**" + push: + branches: [develop, main] + paths-ignore: + - "docs/**" + - "**/*.md" + - ".vscode/**" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +env: + PSSA_VERSION: "1.24.0" + PESTER_VERSION: "5.7.1" + +jobs: + analyze: + name: PSScriptAnalyzer + runs-on: ubuntu-24.04 + timeout-minutes: 10 + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Cache PowerShell modules (Linux) + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + with: + path: ~/.local/share/powershell/Modules + key: linux-psmodules-pssa-${{ env.PSSA_VERSION }} + restore-keys: | + linux-psmodules- + - name: Install PSScriptAnalyzer - run: Install-Module -Name PSScriptAnalyzer -Force -SkipPublisherCheck + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $moduleName = 'PSScriptAnalyzer' + $requiredVersion = [Version]$env:PSSA_VERSION + + $installed = Get-Module -ListAvailable -Name $moduleName | Where-Object { $_.Version -eq $requiredVersion } + if (-not $installed) { + Install-Module -Name $moduleName -RequiredVersion $requiredVersion.ToString() -Scope CurrentUser -Force -AllowClobber + } + + - name: Run PSScriptAnalyzer (repo policy) + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $settingsPath = Join-Path $PWD 'PSScriptAnalyzerSettings.psd1' + if (-not (Test-Path $settingsPath)) { throw "Settings file not found at $settingsPath" } + + $targets = @( + 'modules' + 'scripts' + 'automation/runbooks' + ) | Where-Object { Test-Path $_ } + + if (-not $targets) { + Write-Host "No analyzer targets found; skipping." + exit 0 + } + + $results = foreach ($t in $targets) { + Invoke-ScriptAnalyzer -Path $t -Recurse -Settings $settingsPath + } + + if ($results) { + $results | Format-Table RuleName, Severity, ScriptName, Line, Message -AutoSize + throw "PSScriptAnalyzer found $($results.Count) issue(s)." + } + + test_ps51: + name: Pester (Windows PowerShell 5.1) + runs-on: windows-2022 + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Cache PowerShell modules (Windows) + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + with: + path: ~\Documents\PowerShell\Modules + key: windows-psmodules-pester-${{ env.PESTER_VERSION }} + restore-keys: | + windows-psmodules- + + - name: Install Pester + shell: powershell + run: | + $ErrorActionPreference = 'Stop' + $moduleName = 'Pester' + $requiredVersion = [Version]$env:PESTER_VERSION - # Run PSScriptAnalyzer - - name: Run PSScriptAnalyzer - run: Invoke-ScriptAnalyzer -Path . -Recurse + $installed = Get-Module -ListAvailable -Name $moduleName | Where-Object { $_.Version -eq $requiredVersion } + if (-not $installed) { + Install-Module -Name $moduleName -RequiredVersion $requiredVersion.ToString() -Scope CurrentUser -Force -AllowClobber + } + + - name: Run Pester + shell: powershell + run: | + $ErrorActionPreference = 'Stop' + + $resultsPath = Join-Path $env:GITHUB_WORKSPACE 'Output\TestResults' + New-Item -ItemType Directory -Path $resultsPath -Force | Out-Null + $outFile = Join-Path $resultsPath 'PesterResults_WindowsPowerShell-5.1.xml' + + Import-Module Pester -RequiredVersion $env:PESTER_VERSION -Force + + $paths = @() + + # Module tests: modules/**/Tests + $moduleTests = Get-ChildItem -Path 'modules' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($moduleTests) { $paths += $moduleTests } + + # Script tests: scripts/**/Tests + $scriptTests = Get-ChildItem -Path 'scripts' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($scriptTests) { $paths += $scriptTests } + + if (-not $paths) { + Write-Host 'No Pester tests found (modules/**/Tests or scripts/**/Tests). Skipping.' + exit 0 + } + + $config = [PesterConfiguration]::Default + $config.Run.Path = $paths + $config.Run.PassThru = $true + $config.Output.Verbosity = 'Detailed' + $config.TestResult.Enabled = $true + $config.TestResult.OutputFormat = 'JUnitXml' + $config.TestResult.OutputPath = $outFile + + $result = Invoke-Pester -Configuration $config + if ($result.FailedCount -gt 0) { throw "Pester failures: $($result.FailedCount)" } + + - name: Upload test results + if: always() + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: pester-results-windows-ps51 + path: Output/TestResults/*.xml + retention-days: 14 + if-no-files-found: warn + + test_pwsh7: + name: Pester (PowerShell 7) + runs-on: windows-2022 + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Cache PowerShell modules (Windows) + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + with: + path: ~\Documents\PowerShell\Modules + key: windows-psmodules-pester-${{ env.PESTER_VERSION }} + restore-keys: | + windows-psmodules- - # Install Pester for testing - name: Install Pester - run: Install-Module -Name Pester -Force -SkipPublisherCheck - - # Run Pester tests - - name: Run Pester Tests - run: Invoke-Pester -Path ./tests - - # Uncomment this section when you're ready to add packaging and deployment - # package-and-deploy: - # runs-on: windows-latest - # needs: lint-and-test - # if: github.ref == 'refs/heads/main' # Only run for the main branch - # steps: - # - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - # - # # Package Scripts - # - name: Package Scripts - # run: Compress-Archive -Path ./scripts/* -DestinationPath ./scripts.zip - # - # # Upload Release Asset to GitHub Releases - # - name: Upload Release Asset - # uses: softprops/action-gh-release@v1 - # with: - # files: scripts.zip - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # - # # Deployment steps (uncomment and modify when you're ready) - # - name: Deploy to Remote Server - # run: | - # # Deployment steps here + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $moduleName = 'Pester' + $requiredVersion = [Version]$env:PESTER_VERSION + + $installed = Get-Module -ListAvailable -Name $moduleName | Where-Object { $_.Version -eq $requiredVersion } + if (-not $installed) { + Install-Module -Name $moduleName -RequiredVersion $requiredVersion.ToString() -Scope CurrentUser -Force -AllowClobber + } + + - name: Run Pester + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + + $resultsPath = Join-Path $env:GITHUB_WORKSPACE 'Output/TestResults' + New-Item -ItemType Directory -Path $resultsPath -Force | Out-Null + $outFile = Join-Path $resultsPath 'PesterResults_PowerShell-7.xml' + + Import-Module Pester -RequiredVersion $env:PESTER_VERSION -Force + + $paths = @() + + # Module tests: modules/**/Tests + $moduleTests = Get-ChildItem -Path 'modules' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($moduleTests) { $paths += $moduleTests } + + # Script tests: scripts/**/Tests + $scriptTests = Get-ChildItem -Path 'scripts' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($scriptTests) { $paths += $scriptTests } + + if (-not $paths) { + Write-Host 'No Pester tests found (modules/**/Tests or scripts/**/Tests). Skipping.' + exit 0 + } + + $config = [PesterConfiguration]::Default + $config.Run.Path = $paths + $config.Run.PassThru = $true + $config.Output.Verbosity = 'Detailed' + $config.TestResult.Enabled = $true + $config.TestResult.OutputFormat = 'JUnitXml' + $config.TestResult.OutputPath = $outFile + + $result = Invoke-Pester -Configuration $config + if ($result.FailedCount -gt 0) { throw "Pester failures: $($result.FailedCount)" } + + - name: Upload test results + if: always() + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: pester-results-windows-pwsh7 + path: Output/TestResults/*.xml + retention-days: 14 + if-no-files-found: warn From 6163ec56c220b9501608437f360ed9993c60ff23 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:27:46 -0500 Subject: [PATCH 30/36] Rename CI/CD pipeline workflow file to ci.yml --- .github/workflows/{ci-cd-pipeline.yml => ci.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{ci-cd-pipeline.yml => ci.yml} (100%) diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci.yml similarity index 100% rename from .github/workflows/ci-cd-pipeline.yml rename to .github/workflows/ci.yml From 510331b1d8524247c0258c904321b4873ba54708 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:37:50 -0500 Subject: [PATCH 31/36] Delete ArchiTechLabs-Script-Hub.code-workspace --- ArchiTechLabs-Script-Hub.code-workspace | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 ArchiTechLabs-Script-Hub.code-workspace diff --git a/ArchiTechLabs-Script-Hub.code-workspace b/ArchiTechLabs-Script-Hub.code-workspace deleted file mode 100644 index a03933b..0000000 --- a/ArchiTechLabs-Script-Hub.code-workspace +++ /dev/null @@ -1,14 +0,0 @@ -{ - "folders": [ - { - "path": "." - } - ], - "settings": { - "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true, - "powershell.codeFormatting.useCorrectCasing": true, - "editor.tabSize": 4, - "editor.defaultFormatter": "ms-vscode.powershell" - } -} From ea2aa533125b5b6bdb4df552a263e820db4e4eed Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:41:08 -0500 Subject: [PATCH 32/36] Refactor CI workflow and add runner hardening Updated CI workflow to simplify configuration and ensure consistent runner hardening across all jobs. --- .github/workflows/ci.yml | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8830b14..5957b37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,26 +1,4 @@ -name: PowerShell CI/CD Pipeline - -on: - push: - branches: - - main - - develop - -permissions: - contents: read - -jobs: - lint-and-test: - runs-on: windows-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 - with: - egress-policy: audit - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: CI +name: CI on: pull_request: @@ -55,6 +33,11 @@ jobs: timeout-minutes: 10 steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -111,6 +94,11 @@ jobs: timeout-minutes: 20 steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -190,6 +178,11 @@ jobs: timeout-minutes: 20 steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 From ad9199f13c2512ae7b20521f2e1dd7e26bd778d5 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 13:49:40 -0500 Subject: [PATCH 33/36] Refactor CI workflow for PowerShell testing Updated CI workflow to include PSScriptAnalyzer and Pester tests for both Windows PowerShell 5.1 and PowerShell 7. Adjusted runner settings and module installation steps. --- .github/workflows/ci-cd-pipeline.yml | 62 ------- .github/workflows/ci.yml | 257 +++++++++++++++++++++++++++ 2 files changed, 257 insertions(+), 62 deletions(-) delete mode 100644 .github/workflows/ci-cd-pipeline.yml create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci-cd-pipeline.yml b/.github/workflows/ci-cd-pipeline.yml deleted file mode 100644 index 7a0335f..0000000 --- a/.github/workflows/ci-cd-pipeline.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: PowerShell CI/CD Pipeline - -on: - push: - branches: - - main - - develop - -permissions: - contents: read - -jobs: - lint-and-test: - runs-on: windows-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 - with: - egress-policy: audit - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - # Install PSScriptAnalyzer - - name: Install PSScriptAnalyzer - run: Install-Module -Name PSScriptAnalyzer -Force -SkipPublisherCheck - - # Run PSScriptAnalyzer - - name: Run PSScriptAnalyzer - run: Invoke-ScriptAnalyzer -Path . -Recurse - - # Install Pester for testing - - name: Install Pester - run: Install-Module -Name Pester -Force -SkipPublisherCheck - - # Run Pester tests - - name: Run Pester Tests - run: Invoke-Pester -Path ./tests - - # Uncomment this section when you're ready to add packaging and deployment - # package-and-deploy: - # runs-on: windows-latest - # needs: lint-and-test - # if: github.ref == 'refs/heads/main' # Only run for the main branch - # steps: - # - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - # - # # Package Scripts - # - name: Package Scripts - # run: Compress-Archive -Path ./scripts/* -DestinationPath ./scripts.zip - # - # # Upload Release Asset to GitHub Releases - # - name: Upload Release Asset - # uses: softprops/action-gh-release@v1 - # with: - # files: scripts.zip - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # - # # Deployment steps (uncomment and modify when you're ready) - # - name: Deploy to Remote Server - # run: | - # # Deployment steps here diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5957b37 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,257 @@ +name: CI + +on: + pull_request: + branches: [develop, main] + paths-ignore: + - "docs/**" + - "**/*.md" + - ".vscode/**" + push: + branches: [develop, main] + paths-ignore: + - "docs/**" + - "**/*.md" + - ".vscode/**" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +env: + PSSA_VERSION: "1.24.0" + PESTER_VERSION: "5.7.1" + +jobs: + analyze: + name: PSScriptAnalyzer + runs-on: ubuntu-24.04 + timeout-minutes: 10 + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Cache PowerShell modules (Linux) + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + with: + path: ~/.local/share/powershell/Modules + key: linux-psmodules-pssa-${{ env.PSSA_VERSION }} + restore-keys: | + linux-psmodules- + + - name: Install PSScriptAnalyzer + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $moduleName = 'PSScriptAnalyzer' + $requiredVersion = [Version]$env:PSSA_VERSION + + $installed = Get-Module -ListAvailable -Name $moduleName | Where-Object { $_.Version -eq $requiredVersion } + if (-not $installed) { + Install-Module -Name $moduleName -RequiredVersion $requiredVersion.ToString() -Scope CurrentUser -Force -AllowClobber + } + + - name: Run PSScriptAnalyzer (repo policy) + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $settingsPath = Join-Path $PWD 'PSScriptAnalyzerSettings.psd1' + if (-not (Test-Path $settingsPath)) { throw "Settings file not found at $settingsPath" } + + $targets = @( + 'modules' + 'scripts' + 'automation/runbooks' + ) | Where-Object { Test-Path $_ } + + if (-not $targets) { + Write-Host "No analyzer targets found; skipping." + exit 0 + } + + $results = foreach ($t in $targets) { + Invoke-ScriptAnalyzer -Path $t -Recurse -Settings $settingsPath + } + + if ($results) { + $results | Format-Table RuleName, Severity, ScriptName, Line, Message -AutoSize + throw "PSScriptAnalyzer found $($results.Count) issue(s)." + } + + test_ps51: + name: Pester (Windows PowerShell 5.1) + runs-on: windows-2022 + timeout-minutes: 20 + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Cache PowerShell modules (Windows) + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + with: + path: ~\Documents\PowerShell\Modules + key: windows-psmodules-pester-${{ env.PESTER_VERSION }} + restore-keys: | + windows-psmodules- + + - name: Install Pester + shell: powershell + run: | + $ErrorActionPreference = 'Stop' + $moduleName = 'Pester' + $requiredVersion = [Version]$env:PESTER_VERSION + + $installed = Get-Module -ListAvailable -Name $moduleName | Where-Object { $_.Version -eq $requiredVersion } + if (-not $installed) { + Install-Module -Name $moduleName -RequiredVersion $requiredVersion.ToString() -Scope CurrentUser -Force -AllowClobber + } + + - name: Run Pester + shell: powershell + run: | + $ErrorActionPreference = 'Stop' + + $resultsPath = Join-Path $env:GITHUB_WORKSPACE 'Output\TestResults' + New-Item -ItemType Directory -Path $resultsPath -Force | Out-Null + $outFile = Join-Path $resultsPath 'PesterResults_WindowsPowerShell-5.1.xml' + + Import-Module Pester -RequiredVersion $env:PESTER_VERSION -Force + + $paths = @() + + # Module tests: modules/**/Tests + $moduleTests = Get-ChildItem -Path 'modules' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($moduleTests) { $paths += $moduleTests } + + # Script tests: scripts/**/Tests + $scriptTests = Get-ChildItem -Path 'scripts' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($scriptTests) { $paths += $scriptTests } + + if (-not $paths) { + Write-Host 'No Pester tests found (modules/**/Tests or scripts/**/Tests). Skipping.' + exit 0 + } + + $config = [PesterConfiguration]::Default + $config.Run.Path = $paths + $config.Run.PassThru = $true + $config.Output.Verbosity = 'Detailed' + $config.TestResult.Enabled = $true + $config.TestResult.OutputFormat = 'JUnitXml' + $config.TestResult.OutputPath = $outFile + + $result = Invoke-Pester -Configuration $config + if ($result.FailedCount -gt 0) { throw "Pester failures: $($result.FailedCount)" } + + - name: Upload test results + if: always() + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: pester-results-windows-ps51 + path: Output/TestResults/*.xml + retention-days: 14 + if-no-files-found: warn + + test_pwsh7: + name: Pester (PowerShell 7) + runs-on: windows-2022 + timeout-minutes: 20 + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Cache PowerShell modules (Windows) + uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + with: + path: ~\Documents\PowerShell\Modules + key: windows-psmodules-pester-${{ env.PESTER_VERSION }} + restore-keys: | + windows-psmodules- + + - name: Install Pester + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $moduleName = 'Pester' + $requiredVersion = [Version]$env:PESTER_VERSION + + $installed = Get-Module -ListAvailable -Name $moduleName | Where-Object { $_.Version -eq $requiredVersion } + if (-not $installed) { + Install-Module -Name $moduleName -RequiredVersion $requiredVersion.ToString() -Scope CurrentUser -Force -AllowClobber + } + + - name: Run Pester + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + + $resultsPath = Join-Path $env:GITHUB_WORKSPACE 'Output/TestResults' + New-Item -ItemType Directory -Path $resultsPath -Force | Out-Null + $outFile = Join-Path $resultsPath 'PesterResults_PowerShell-7.xml' + + Import-Module Pester -RequiredVersion $env:PESTER_VERSION -Force + + $paths = @() + + # Module tests: modules/**/Tests + $moduleTests = Get-ChildItem -Path 'modules' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($moduleTests) { $paths += $moduleTests } + + # Script tests: scripts/**/Tests + $scriptTests = Get-ChildItem -Path 'scripts' -Directory -Recurse -ErrorAction SilentlyContinue | + Where-Object { $_.Name -eq 'Tests' } | + ForEach-Object { $_.FullName } + if ($scriptTests) { $paths += $scriptTests } + + if (-not $paths) { + Write-Host 'No Pester tests found (modules/**/Tests or scripts/**/Tests). Skipping.' + exit 0 + } + + $config = [PesterConfiguration]::Default + $config.Run.Path = $paths + $config.Run.PassThru = $true + $config.Output.Verbosity = 'Detailed' + $config.TestResult.Enabled = $true + $config.TestResult.OutputFormat = 'JUnitXml' + $config.TestResult.OutputPath = $outFile + + $result = Invoke-Pester -Configuration $config + if ($result.FailedCount -gt 0) { throw "Pester failures: $($result.FailedCount)" } + + - name: Upload test results + if: always() + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: pester-results-windows-pwsh7 + path: Output/TestResults/*.xml + retention-days: 14 + if-no-files-found: warn From 329d3285577878805d268192839ee74a4332f6c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:05:08 +0000 Subject: [PATCH 34/36] chore(deps): bump step-security/harden-runner Bumps the github-actions-minor-patch group with 1 update: [step-security/harden-runner](https://github.com/step-security/harden-runner). Updates `step-security/harden-runner` from 2.14.1 to 2.15.1 - [Release notes](https://github.com/step-security/harden-runner/releases) - [Commits](https://github.com/step-security/harden-runner/compare/v2.14.1...58077d3c7e43986b6b15fba718e8ea69e387dfcc) --- updated-dependencies: - dependency-name: step-security/harden-runner dependency-version: 2.15.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-minor-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5957b37..7522f98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 with: egress-policy: audit @@ -95,7 +95,7 @@ jobs: steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 with: egress-policy: audit @@ -179,7 +179,7 @@ jobs: steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@e3f713f2d8f53843e71c69a996d56f51aa9adfb9 # v2.14.1 + uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1 with: egress-policy: audit From 3c394feb4359fc6b34e81afd2f7e86da7a66b471 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:05:15 +0000 Subject: [PATCH 35/36] chore(deps): bump actions/upload-artifact from 6.0.0 to 7.0.0 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5957b37..62ba437 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -165,7 +165,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pester-results-windows-ps51 path: Output/TestResults/*.xml @@ -249,7 +249,7 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pester-results-windows-pwsh7 path: Output/TestResults/*.xml From b138f2a533e0afc1423520fee65de7892116c312 Mon Sep 17 00:00:00 2001 From: Travis McDade Date: Fri, 6 Mar 2026 14:12:39 -0500 Subject: [PATCH 36/36] Update README with new CI and Dependabot badges --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 673248b..dd87127 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # ArchiTechLabs Script Hub -![Build Status](https://img.shields.io/github/workflow/status/thetechgy/ArchiTechLabs-Script-Hub/PowerShell%20CI%2FCD%20Pipeline) +[![CI](https://github.com/thetechgy/ArchiTechLabs-Script-Hub/actions/workflows/ci.yml/badge.svg?branch=develop)](https://github.com/thetechgy/ArchiTechLabs-Script-Hub/actions/workflows/ci.yml) +[![Dependabot](https://img.shields.io/badge/Dependabot-enabled-025e8c?logo=dependabot)](https://github.com/thetechgy/ArchiTechLabs-Script-Hub//network/updates) +[![PowerShell](https://img.shields.io/badge/PowerShell-5.1%20%7C%207.x-2671E5)](#requirements)