From 87a7470141fa5db09f7316f53ea88beed2fb2611 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 13:04:20 -0400 Subject: [PATCH 1/9] Pin GH Actions, tighten perms, tweak Dependabot Pin several GitHub Actions and third-party workflow refs to specific SHAs/digests for reproducible runs; add permissions (contents/id-token/pages) where required for coverage uploads, OIDC and docs publishing; set persist-credentials: false on checkouts and adjust run images/digests. Also add a 7-day Dependabot cooldown and minor CI tweaks (ubuntu-slim for docs comment, curl env fix for release input). These changes improve security, stability and reduce noisy Dependabot updates. --- .github/dependabot.yml | 2 ++ .github/workflows/ansible-test-windows.yml | 17 ++++++++++---- .github/workflows/ansible-test.yml | 20 ++++++++++------ .github/workflows/docs-pr.yml | 27 +++++++++++----------- .github/workflows/docs-push.yml | 15 ++++++------ .github/workflows/release.yml | 16 +++++++++---- 6 files changed, 58 insertions(+), 39 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 443cf3be..b1659a53 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,5 @@ updates: schedule: # Check for updates to GitHub Actions every weekday interval: "daily" + cooldown: + default-days: 7 diff --git a/.github/workflows/ansible-test-windows.yml b/.github/workflows/ansible-test-windows.yml index f922edc1..10ae9df6 100644 --- a/.github/workflows/ansible-test-windows.yml +++ b/.github/workflows/ansible-test-windows.yml @@ -62,11 +62,18 @@ jobs: run: shell: wsl-bash {0} + permissions: + # Required for uploading coverage reports + contents: write + # Required for OIDC token authentication + id-token: write + steps: - name: Check out code - uses: actions/checkout@v6 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 with: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} + persist-credentials: false - name: Create an admin user shell: cmd @@ -94,7 +101,7 @@ jobs: shell: cmd run: echo 127.0.0.1 sqlserver >> "%WinDir%\System32\Drivers\etc\hosts" - - uses: Vampire/setup-wsl@v6.0.0 + - uses: Vampire/setup-wsl@f9577ca4c38935b96f9e985505bb5973a11efe48 # v6.0.0 with: distribution: ${{ matrix.wsl }} update: "false" @@ -157,7 +164,7 @@ jobs: - name: Install SQL Server continue-on-error: true id: mssqlsuite - uses: potatoqualitee/mssqlsuite@v1.12 + uses: potatoqualitee/mssqlsuite@2291d923e83859edd871679c05b379037376761f # v1.12 with: install: sqlengine sa-password: L0wlydb4 @@ -166,7 +173,7 @@ jobs: - name: Retry SQL Server install id: retry1 if: steps.mssqlsuite.outcome == 'failure' - uses: potatoqualitee/mssqlsuite@v1.12 + uses: potatoqualitee/mssqlsuite@2291d923e83859edd871679c05b379037376761f with: install: sqlengine sa-password: L0wlydb4 @@ -183,7 +190,7 @@ jobs: ansible-test coverage xml -v --requirements # See the reports at https://codecov.io/gh/lowlydba/lowlydba.sqlserver - - uses: codecov/codecov-action@v6.0.0 + - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false env: diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 933a53c1..9a65f0dc 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -47,6 +47,8 @@ jobs: sanity: name: Sanity (Ⓐ${{ matrix.ansible }}) + permissions: + contents: write # Required for uploading coverage reports strategy: matrix: # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix @@ -62,12 +64,13 @@ jobs: # .../ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}/ - name: Check out code - uses: actions/checkout@v6 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 with: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} + persist-credentials: false - name: Run confidence tests - uses: ansible-community/ansible-test-gh-action@v1.17.0 + uses: ansible-community/ansible-test-gh-action@9e1c70a1e9c97c666c4e578d8c021f65501cffb8 # v1.17.0 with: ansible-core-version: ${{ matrix.ansible }} testing-type: sanity @@ -78,7 +81,7 @@ jobs: working-directory: ./ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} # See the reports at https://codecov.io/gh/lowlydba/lowlydba.sqlserver - - uses: codecov/codecov-action@v6.0.0 + - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false env: @@ -96,9 +99,11 @@ jobs: integration: runs-on: ubuntu-latest name: I (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }}) + permissions: + contents: write # Required for uploading coverage reports services: sqlserver: - image: mcr.microsoft.com/mssql/server:2022-latest + image: mcr.microsoft.com/mssql/server@sha256:c9f2f1560c56b6aea104f08cd1fc24daf964e149002fddef7c606da48141ad1f ports: - 1433:1433 env: @@ -116,16 +121,17 @@ jobs: steps: - name: Check out code - uses: actions/checkout@v6 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 with: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} + persist-credentials: false - name: Set integration test options working-directory: ./ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}/tests/integration run: cp integration_config.sample.yml integration_config.yml - name: Run integration tests - uses: ansible-community/ansible-test-gh-action@v1.17.0 + uses: ansible-community/ansible-test-gh-action@9e1c70a1e9c97c666c4e578d8c021f65501cffb8 # v1.17.0 with: ansible-core-version: ${{ matrix.ansible }} testing-type: integration @@ -138,7 +144,7 @@ jobs: working-directory: ./ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} # See the reports at https://codecov.io/gh/lowlydba/lowlydba.sqlserver - - uses: codecov/codecov-action@v6.0.0 + - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false env: diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index d7c06ba5..07a5d63d 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -10,8 +10,7 @@ env: GHP_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }} permissions: - pages: write - id-token: write + contents: read jobs: validate-docs: @@ -19,7 +18,7 @@ jobs: contents: read name: Validate Ansible Docs if: github.event.action != 'closed' - uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@main + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@50bb8f670ad5ff11443bd94e51369debb8d34775 # main with: artifact-upload: false init-lenient: false @@ -28,11 +27,11 @@ jobs: build-docs: permissions: - contents: read - pages: write - id-token: write + contents: read # Required for reading collection content + pages: write # Required for publishing docs to GitHub Pages + id-token: write # Required for OIDC authentication name: Build Ansible Docs - uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@main + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@50bb8f670ad5ff11443bd94e51369debb8d34775 # main with: init-lenient: true init-fail-on-error: false @@ -42,12 +41,12 @@ jobs: # for now we won't run this on forks if: github.repository == 'lowlydba/lowlydba.sqlserver' permissions: - contents: write - pages: write - id-token: write + contents: write # Required for writing release/tag artifacts + pages: write # Required for publishing docs to GitHub Pages + id-token: write # Required for OIDC authentication needs: [build-docs] name: Publish Ansible Docs - uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-publish-gh-pages.yml@main + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-publish-gh-pages.yml@50bb8f670ad5ff11443bd94e51369debb8d34775 # main with: artifact-name: ${{ needs.build-docs.outputs.artifact-name }} action: ${{ (github.event.action == 'closed' || needs.build-docs.outputs.changed != 'true') && 'teardown' || 'publish' }} @@ -56,13 +55,13 @@ jobs: comment: permissions: - pull-requests: write - runs-on: ubuntu-latest + pull-requests: write # Required for commenting on PRs + runs-on: ubuntu-slim needs: [publish-docs-gh-pages, build-docs] name: PR comments steps: - name: PR comment - uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@main + uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@50bb8f670ad5ff11443bd94e51369debb8d34775 # main with: body-includes: '## Docs Build' reactions: heart diff --git a/.github/workflows/docs-push.yml b/.github/workflows/docs-push.yml index 05829255..3c7c6324 100644 --- a/.github/workflows/docs-push.yml +++ b/.github/workflows/docs-push.yml @@ -12,15 +12,14 @@ on: - cron: '0 13 * * *' permissions: - pages: write - id-token: write + contents: read # Required for reading collection content jobs: build-docs: permissions: - contents: read + contents: read # Required for reading collection content name: Build Ansible Docs - uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@main + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-push.yml@50bb8f670ad5ff11443bd94e51369debb8d34775 # main with: init-lenient: false init-fail-on-error: true @@ -29,12 +28,12 @@ jobs: # for now we won't run this on forks if: github.repository == 'lowlydba/lowlydba.sqlserver' permissions: - contents: write - pages: write - id-token: write + contents: write # Required for writing release/tag artifacts + pages: write # Required for publishing docs to GitHub Pages + id-token: write # Required for OIDC authentication needs: [build-docs] name: Publish Ansible Docs - uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-publish-gh-pages.yml@main + uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-publish-gh-pages.yml@50bb8f670ad5ff11443bd94e51369debb8d34775 # main with: artifact-name: ${{ needs.build-docs.outputs.artifact-name }} secrets: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b5dfbeaa..8334fa36 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,12 +13,16 @@ jobs: release: name: Create GitHub Release runs-on: ubuntu-latest + permissions: + contents: write # Required for creating releases and tags steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 + with: + persist-credentials: false - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@28f2168f4d98ee0445e3c6321f6e6616c83dd5ec # v6 with: python-version: 3.8 @@ -26,12 +30,14 @@ jobs: run: pip install pyyaml - name: Publish to Galaxy - uses: artis3n/ansible_galaxy_collection@v3.0.0 + uses: artis3n/ansible_galaxy_collection@325f5822aea7846e7d46a2522456898e9295acf2 # v3.0.0 with: api_key: ${{ secrets.GALAXY_API_KEY }} - name: Validate version is published to Galaxy - run: curl --head -s -f -o /dev/null https://galaxy.ansible.com/download/lowlydba-sqlserver-${{ github.event.inputs.version }}.tar.gz + run: curl --head -s -f -o /dev/null https://galaxy.ansible.com/download/lowlydba-sqlserver-${GITHUB_EVENT_INPUTS_VERSION}.tar.gz + env: + GITHUB_EVENT_INPUTS_VERSION: ${{ github.event.inputs.version }} - name: Build release description shell: python @@ -69,7 +75,7 @@ jobs: - name: Create Release id: create_release - uses: softprops/action-gh-release@v2.6.1 + uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From e16af62cd2d261cfb84baa085a6e03663407b501 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 13:15:20 -0400 Subject: [PATCH 2/9] Harden workflows, set envs, and fix actions Tighten and standardize GitHub Actions across workflows: - ansible-test-windows.yml: deny workflow-level permissions (scope per job), add job env (NAMESPACE, COLLECTION_NAME, GHWS, CODECOV_TOKEN), and switch pip invocations to python3 (remove matrix.python usage). Keep id-token and other required permissions per job. - ansible-test.yml: restrict default permissions (contents: read), expose CODECOV_TOKEN as job env for Sanity and Integration jobs, and remove duplicated env on codecov steps. - docs-pr.yml: change trigger from pull_request_target to pull_request to avoid elevated token scope for PRs. - release.yml: add concurrency and restrict default permissions (contents: read), expose VERSION, GALAXY_API_KEY, and GITHUB_TOKEN to the release job, and fix the Galaxy validation curl to use the VERSION env var. Overall these changes improve security (reduce default permissions), ensure required secrets/envs are available to jobs, and fix platform-specific command usage and release validation. --- .github/workflows/ansible-test-windows.yml | 20 ++++++++++++++++---- .github/workflows/ansible-test.yml | 12 ++++++++---- .github/workflows/docs-pr.yml | 2 +- .github/workflows/release.yml | 16 ++++++++++++++-- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ansible-test-windows.yml b/.github/workflows/ansible-test-windows.yml index 10ae9df6..605f80a1 100644 --- a/.github/workflows/ansible-test-windows.yml +++ b/.github/workflows/ansible-test-windows.yml @@ -27,6 +27,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Deny all permissions at workflow level - scope per job +permissions: {} + env: NAMESPACE: lowlydba COLLECTION_NAME: sqlserver @@ -67,6 +70,15 @@ jobs: contents: write # Required for OIDC token authentication id-token: write + env: + NAMESPACE: lowlydba + COLLECTION_NAME: sqlserver + GHWS: ${{ env.GHWS }} + GROUP: ${{ matrix.group }} + ANSIBLE: ${{ matrix.ansible }} + PYTHON: python3 + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + WORKSPACE: ${{ github.workspace }} steps: - name: Check out code @@ -140,11 +152,11 @@ jobs: Add-Content -LiteralPath $env:GITHUB_ENV -Value "GHWS=$ws" # Override break-sys-pkg defaults, because we don't need to bother with python venv for CI - - name: Install ansible-base (${{ matrix.ansible }}) + - name: Install ansible-base run: | - ${{ matrix.python }} -m pip config set global.break-system-packages true - ${{ matrix.python }} -m pip install --upgrade setuptools pypsrp --disable-pip-version-check --retries 10 - ${{ matrix.python }} -m pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check --retries 10 + python3 -m pip config set global.break-system-packages true + python3 -m pip install --upgrade setuptools pypsrp --disable-pip-version-check --retries 10 + python3 -m pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check --retries 10 - name: Install collection dependencies id: collection-dependency diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 9a65f0dc..9094b9fd 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -35,6 +35,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# Restrict default permissions for security +permissions: + contents: read + env: NAMESPACE: lowlydba COLLECTION_NAME: sqlserver @@ -49,6 +53,8 @@ jobs: name: Sanity (Ⓐ${{ matrix.ansible }}) permissions: contents: write # Required for uploading coverage reports + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} strategy: matrix: # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix @@ -84,8 +90,6 @@ jobs: - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} ### # Integration tests (RECOMMENDED) @@ -101,6 +105,8 @@ jobs: name: I (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }}) permissions: contents: write # Required for uploading coverage reports + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} services: sqlserver: image: mcr.microsoft.com/mssql/server@sha256:c9f2f1560c56b6aea104f08cd1fc24daf964e149002fddef7c606da48141ad1f @@ -147,5 +153,3 @@ jobs: - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index 07a5d63d..aa4b70d6 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -3,7 +3,7 @@ concurrency: group: docs-pr-${{ github.head_ref }} cancel-in-progress: true on: - pull_request_target: + pull_request: types: [opened, synchronize, reopened, closed] env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8334fa36..7d794167 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,14 @@ on: description: "Version number to release" required: true +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: true + +# Restrict default permissions for security +permissions: + contents: read + env: GHP_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }} @@ -15,6 +23,10 @@ jobs: runs-on: ubuntu-latest permissions: contents: write # Required for creating releases and tags + env: + VERSION: ${{ github.event.inputs.version }} + GALAXY_API_KEY: ${{ secrets.GALAXY_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Checkout uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 @@ -35,9 +47,9 @@ jobs: api_key: ${{ secrets.GALAXY_API_KEY }} - name: Validate version is published to Galaxy - run: curl --head -s -f -o /dev/null https://galaxy.ansible.com/download/lowlydba-sqlserver-${GITHUB_EVENT_INPUTS_VERSION}.tar.gz + run: curl --head -s -f -o /dev/null https://galaxy.ansible.com/download/lowlydba-sqlserver-${VERSION}.tar.gz env: - GITHUB_EVENT_INPUTS_VERSION: ${{ github.event.inputs.version }} + VERSION: ${{ github.event.inputs.version }} - name: Build release description shell: python From d3aa680414bf1b746d8594a82cb489d0f23a82d6 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 13:25:11 -0400 Subject: [PATCH 3/9] Annotate workflows and parameterize env vars Add zizmor ignore annotations and comments to GitHub Actions workflows, tighten workflow-level permissions (set to {} to scope per-job), and propagate environment variables into relevant steps. Replace inline matrix/github workspace usages with step env vars (e.g. ANSIBLE, GHWS, NAMESPACE, COLLECTION_NAME, GROUP) for pip installs, ansible-test invocations, and coverage/reporting steps; adjust WSL path conversion to use WORKSPACE env. Add explanatory comments for CODECOV_TOKEN and secrets usage. In release workflow, switch to using env.VERSION/GHP_BASE_URL/GALAXY_API_KEY/GITHUB_TOKEN, fix curl quoting, update Python release description to reference env variables, and annotate the release action usage. These changes improve lint suppression, environment scoping, and consistency across jobs. --- .github/workflows/ansible-test-windows.yml | 51 +++++++++++++--------- .github/workflows/ansible-test.yml | 13 +++--- .github/workflows/release.yml | 37 ++++++++-------- .github/workflows/zizmor.yml | 31 +++++++++++++ 4 files changed, 86 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/ansible-test-windows.yml b/.github/workflows/ansible-test-windows.yml index 605f80a1..30a8db87 100644 --- a/.github/workflows/ansible-test-windows.yml +++ b/.github/workflows/ansible-test-windows.yml @@ -67,27 +67,27 @@ jobs: permissions: # Required for uploading coverage reports - contents: write + contents: write # Required for uploading coverage reports # Required for OIDC token authentication - id-token: write + id-token: write # Required for OIDC token authentication env: - NAMESPACE: lowlydba - COLLECTION_NAME: sqlserver - GHWS: ${{ env.GHWS }} - GROUP: ${{ matrix.group }} - ANSIBLE: ${{ matrix.ansible }} + NAMESPACE: lowlydba # zizmor: ignore[template-injection] -- Static value + COLLECTION_NAME: sqlserver # zizmor: ignore[template-injection] -- Static value + GHWS: ${{ env.GHWS }} # zizmor: ignore[template-injection] -- Dynamically computed in earlier step + GROUP: ${{ matrix.group }} # zizmor: ignore[template-injection] -- Matrix value from controlled environment + ANSIBLE: ${{ matrix.ansible }} # zizmor: ignore[template-injection] -- Matrix value from controlled environment PYTHON: python3 - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for coverage uploads; environment protection would block PR-triggered runs WORKSPACE: ${{ github.workspace }} steps: - name: Check out code - uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} persist-credentials: false - - name: Create an admin user + - name: Create an admin user # zizmor: ignore[misfeature] -- Windows-specific cmd required for net user commands; pwsh cannot create local users shell: cmd run: | net user admin pass123@ /add /y @@ -109,7 +109,7 @@ jobs: run: | Get-Service -Name MongoDB | Where-Object Status -eq 'Running' | Stop-Service -Force - - name: Add a hosts entry + - name: Add a hosts entry # zizmor: ignore[misfeature] -- Windows-specific cmd required for hosts file modification shell: cmd run: echo 127.0.0.1 sqlserver >> "%WinDir%\System32\Drivers\etc\hosts" @@ -128,7 +128,7 @@ jobs: - name: Get Linux workspace path shell: pwsh run: | - # $ws = & wslpath --% -u -a "${{ github.workspace }}"" + # $ws = & wslpath --% -u -a "$env:WORKSPACE"" # seems wslpath is not available on server 2019 function ConvertTo-LinuxPathCrappy { @@ -148,23 +148,27 @@ jobs: '/mnt/{0}/{1}' -f $drive, $rooted } } - $ws = ConvertTo-LinuxPathCrappy -LiteralPath "${{ github.workspace }}" + $ws = ConvertTo-LinuxPathCrappy -LiteralPath "$env:WORKSPACE" Add-Content -LiteralPath $env:GITHUB_ENV -Value "GHWS=$ws" # Override break-sys-pkg defaults, because we don't need to bother with python venv for CI - name: Install ansible-base + env: + ANSIBLE: ${{ matrix.ansible }} run: | python3 -m pip config set global.break-system-packages true python3 -m pip install --upgrade setuptools pypsrp --disable-pip-version-check --retries 10 - python3 -m pip install https://github.com/ansible/ansible/archive/${{ matrix.ansible }}.tar.gz --disable-pip-version-check --retries 10 + python3 -m pip install "https://github.com/ansible/ansible/archive/$ANSIBLE.tar.gz" --disable-pip-version-check --retries 10 - name: Install collection dependencies id: collection-dependency + # zizmor: ignore[template-injection] -- GHWS is dynamically computed earlier in the workflow run: ansible-galaxy collection install ansible.windows -p "${{ env.GHWS }}" continue-on-error: true - name: Retry install collection dependencies if: steps.collection-dependency.outcome == 'failure' + # zizmor: ignore[template-injection] -- GHWS is dynamically computed earlier in the workflow run: ansible-galaxy collection install ansible.windows -p "${{ env.GHWS }}" - name: Set integration test options @@ -185,25 +189,32 @@ jobs: - name: Retry SQL Server install id: retry1 if: steps.mssqlsuite.outcome == 'failure' - uses: potatoqualitee/mssqlsuite@2291d923e83859edd871679c05b379037376761f + uses: potatoqualitee/mssqlsuite@2291d923e83859edd871679c05b379037376761f # v1.12 with: install: sqlengine sa-password: L0wlydb4 version: 2022 - name: Run integration test + env: + GHWS: ${{ env.GHWS }} + NAMESPACE: ${{ env.NAMESPACE }} + COLLECTION_NAME: ${{ env.COLLECTION_NAME }} + GROUP: ${{ env.GROUP }} run: | - pushd "${{ env.GHWS }}/ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}" - ansible-test windows-integration -v --color --retry-on-error --continue-on-error --diff --coverage --requirements windows/group/${{ matrix.group }}/ + pushd "$GHWS/ansible_collections/$NAMESPACE/$COLLECTION_NAME" + ansible-test windows-integration -v --color --retry-on-error --continue-on-error --diff --coverage --requirements windows/group/$GROUP/ - name: Generate coverage report + env: + GHWS: ${{ env.GHWS }} + NAMESPACE: ${{ env.NAMESPACE }} + COLLECTION_NAME: ${{ env.COLLECTION_NAME }} run: | - pushd "${{ env.GHWS }}/ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}" + pushd "$GHWS/ansible_collections/$NAMESPACE/$COLLECTION_NAME" ansible-test coverage xml -v --requirements # See the reports at https://codecov.io/gh/lowlydba/lowlydba.sqlserver - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 9094b9fd..781d1721 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -35,9 +35,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -# Restrict default permissions for security -permissions: - contents: read +# Deny all permissions at workflow level - scope per job +permissions: {} env: NAMESPACE: lowlydba @@ -54,7 +53,7 @@ jobs: permissions: contents: write # Required for uploading coverage reports env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for coverage uploads; environment protection would block PR-triggered runs strategy: matrix: # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix @@ -70,7 +69,7 @@ jobs: # .../ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}}/ - name: Check out code - uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} persist-credentials: false @@ -106,7 +105,7 @@ jobs: permissions: contents: write # Required for uploading coverage reports env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for coverage uploads; environment protection would block PR-triggered runs services: sqlserver: image: mcr.microsoft.com/mssql/server@sha256:c9f2f1560c56b6aea104f08cd1fc24daf964e149002fddef7c606da48141ad1f @@ -127,7 +126,7 @@ jobs: steps: - name: Check out code - uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: path: ansible_collections/${{env.NAMESPACE}}/${{env.COLLECTION_NAME}} persist-credentials: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d794167..6ec9ff2b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,9 +10,8 @@ concurrency: group: release-${{ github.ref }} cancel-in-progress: true -# Restrict default permissions for security -permissions: - contents: read +# Deny all permissions at workflow level - scope per job +permissions: {} env: GHP_BASE_URL: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }} @@ -24,12 +23,13 @@ jobs: permissions: contents: write # Required for creating releases and tags env: - VERSION: ${{ github.event.inputs.version }} - GALAXY_API_KEY: ${{ secrets.GALAXY_API_KEY }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ github.event.inputs.version }} # zizmor: ignore[template-injection] -- User input is required for this workflow + GHP_BASE_URL: ${{ env.GHP_BASE_URL }} # zizmor: ignore[template-injection] -- Set at workflow level + GALAXY_API_KEY: ${{ secrets.GALAXY_API_KEY }} # zizmor: ignore[secrets-outside-env] -- Galaxy API key needed for publishing; workflow_dispatch only + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # zizmor: ignore[secrets-outside-env] -- GitHub token needed for release creation; workflow_dispatch only steps: - name: Checkout - uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false @@ -44,20 +44,21 @@ jobs: - name: Publish to Galaxy uses: artis3n/ansible_galaxy_collection@325f5822aea7846e7d46a2522456898e9295acf2 # v3.0.0 with: - api_key: ${{ secrets.GALAXY_API_KEY }} + api_key: ${{ env.GALAXY_API_KEY }} - name: Validate version is published to Galaxy - run: curl --head -s -f -o /dev/null https://galaxy.ansible.com/download/lowlydba-sqlserver-${VERSION}.tar.gz - env: - VERSION: ${{ github.event.inputs.version }} + run: curl --head -s -f -o /dev/null "https://galaxy.ansible.com/download/lowlydba-sqlserver-${VERSION}.tar.gz" - name: Build release description shell: python + env: + VERSION: ${{ env.VERSION }} + GHP_BASE_URL: ${{ env.GHP_BASE_URL }} run: | import os import yaml - ver = '${{ github.event.inputs.version }}' + ver = '$VERSION' ver_anchor = str.replace(ver, '.', '-') with open('changelogs/changelog.yaml', 'r') as s: @@ -79,19 +80,17 @@ jobs: View the [complete changelog](https://github.com/lowlydba/lowlydba.sqlserver/blob/main/CHANGELOG.rst#v%s) to see all changes. - View the [full documentation for release ${{ github.event.inputs.version }}](${{ env.GHP_BASE_URL }}/tag/${{ github.event.inputs.version }}). - ''' % (reldate, summary, ver_anchor) + View the [full documentation for release %s](%s/tag/%s). + ''' % (reldate, summary, ver_anchor, ver, os.environ['GHP_BASE_URL'], ver) with open(os.environ['GITHUB_ENV'], 'a') as e: e.write("RELEASE_DESCRIPTION< Date: Sat, 11 Apr 2026 13:41:32 -0400 Subject: [PATCH 4/9] Update pinned GitHub Action SHAs in workflows Bump pinned action commit SHAs across CI workflows to use newer/stable revisions and add a note for docs action: - .github/workflows/ansible-test-windows.yml: Vampire/setup-wsl pinned to v6.1.0 - .github/workflows/ansible-test.yml: ansible-community/ansible-test-gh-action updated to a newer SHA for both sanity and integration jobs - .github/workflows/docs-pr.yml: ansible-docs-build-comment usage kept on the same SHA but annotated to ignore stale-action-refs - .github/workflows/release.yml: actions/setup-python pinned to v6.2.0 and artis3n/ansible_galaxy_collection SHA updated These changes refresh action references to pick up fixes/updates and clarify the docs action pin. --- .github/workflows/ansible-test-windows.yml | 2 +- .github/workflows/ansible-test.yml | 4 ++-- .github/workflows/docs-pr.yml | 2 +- .github/workflows/release.yml | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ansible-test-windows.yml b/.github/workflows/ansible-test-windows.yml index 30a8db87..ac4a6ae1 100644 --- a/.github/workflows/ansible-test-windows.yml +++ b/.github/workflows/ansible-test-windows.yml @@ -113,7 +113,7 @@ jobs: shell: cmd run: echo 127.0.0.1 sqlserver >> "%WinDir%\System32\Drivers\etc\hosts" - - uses: Vampire/setup-wsl@f9577ca4c38935b96f9e985505bb5973a11efe48 # v6.0.0 + - uses: Vampire/setup-wsl@887f39deb6c0976365e546926fe66f41b77d65ff # v6.1.0 with: distribution: ${{ matrix.wsl }} update: "false" diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 781d1721..8d6e9f0d 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -75,7 +75,7 @@ jobs: persist-credentials: false - name: Run confidence tests - uses: ansible-community/ansible-test-gh-action@9e1c70a1e9c97c666c4e578d8c021f65501cffb8 # v1.17.0 + uses: ansible-community/ansible-test-gh-action@d3a8ec7a59694e25e210fcd44738910149537f0e # v1.17.0 with: ansible-core-version: ${{ matrix.ansible }} testing-type: sanity @@ -136,7 +136,7 @@ jobs: run: cp integration_config.sample.yml integration_config.yml - name: Run integration tests - uses: ansible-community/ansible-test-gh-action@9e1c70a1e9c97c666c4e578d8c021f65501cffb8 # v1.17.0 + uses: ansible-community/ansible-test-gh-action@d3a8ec7a59694e25e210fcd44738910149537f0e # v1.17.0 with: ansible-core-version: ${{ matrix.ansible }} testing-type: integration diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index aa4b70d6..c45afc6d 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -61,7 +61,7 @@ jobs: name: PR comments steps: - name: PR comment - uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@50bb8f670ad5ff11443bd94e51369debb8d34775 # main + uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@50bb8f670ad5ff11443bd94e51369debb8d34775 # zizmor: ignore[stale-action-refs] -- Using main branch SHA of ansible-community maintained action; branch is stable with: body-includes: '## Docs Build' reactions: heart diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6ec9ff2b..dd0ff752 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: persist-credentials: false - name: Set up Python - uses: actions/setup-python@28f2168f4d98ee0445e3c6321f6e6616c83dd5ec # v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.8 @@ -42,7 +42,7 @@ jobs: run: pip install pyyaml - name: Publish to Galaxy - uses: artis3n/ansible_galaxy_collection@325f5822aea7846e7d46a2522456898e9295acf2 # v3.0.0 + uses: artis3n/ansible_galaxy_collection@ffbca2460a5a1c600b941bbf1536bd61de1c2227 # v3.0.0 with: api_key: ${{ env.GALAXY_API_KEY }} From 0beb393c0a8e3cf596db6f777783f87b8ec884ea Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 13:47:15 -0400 Subject: [PATCH 5/9] Update ansible-test.yml --- .github/workflows/ansible-test.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index 8d6e9f0d..dd2246d4 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -52,8 +52,6 @@ jobs: name: Sanity (Ⓐ${{ matrix.ansible }}) permissions: contents: write # Required for uploading coverage reports - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for coverage uploads; environment protection would block PR-triggered runs strategy: matrix: # https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix @@ -89,6 +87,8 @@ jobs: - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} ### # Integration tests (RECOMMENDED) @@ -104,11 +104,9 @@ jobs: name: I (Ⓐ${{ matrix.ansible }}+py${{ matrix.python }}) permissions: contents: write # Required for uploading coverage reports - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for coverage uploads; environment protection would block PR-triggered runs services: sqlserver: - image: mcr.microsoft.com/mssql/server@sha256:c9f2f1560c56b6aea104f08cd1fc24daf964e149002fddef7c606da48141ad1f + image: mcr.microsoft.com/mssql/server:2022-latest ports: - 1433:1433 env: @@ -152,3 +150,5 @@ jobs: - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: fail_ci_if_error: false + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 724625e5ade675367a0d9f07c4b98f9d43aa7fbf Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 13:49:36 -0400 Subject: [PATCH 6/9] Add zizmor ignore annotations to CI workflow Add inline zizmor ignore comments to .github/workflows/ansible-test.yml to suppress lint warnings: mark CODECOV_TOKEN env usages with secrets-outside-env (Codecov token required for uploading coverage, used only with workflow_dispatch) and mark the mcr.microsoft.com/mssql/server image with unpinned-images (trusted publisher for this CI use case). These comments silence false positives from security/lint tooling while preserving intended CI behavior. --- .github/workflows/ansible-test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index dd2246d4..ed876190 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -88,7 +88,7 @@ jobs: with: fail_ci_if_error: false env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for uploading coverage; workflow_dispatch only ### # Integration tests (RECOMMENDED) @@ -106,7 +106,7 @@ jobs: contents: write # Required for uploading coverage reports services: sqlserver: - image: mcr.microsoft.com/mssql/server:2022-latest + image: mcr.microsoft.com/mssql/server:2022-latest # zizmor: ignore[unpinned-images] -- Trusted publisher for this CI use case ports: - 1433:1433 env: @@ -151,4 +151,4 @@ jobs: with: fail_ci_if_error: false env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # zizmor: ignore[secrets-outside-env] -- Codecov token needed for uploading coverage; workflow_dispatch only From 098792ada2881d6eed006ef277df8a7495cca8d2 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 14:00:17 -0400 Subject: [PATCH 7/9] Update zizmor.yml --- .github/workflows/zizmor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index f65402a1..b17afef1 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -29,3 +29,4 @@ jobs: uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 with: persona: pedantic + advanced-security: false From 487f30c9f60e46bfeec07c52fdc3e6e7bf2b6a7c Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 14:04:01 -0400 Subject: [PATCH 8/9] Use PR number in Actions concurrency groups Update GitHub Actions concurrency group expressions to use github.event.pull_request.number || github.ref (or for docs-pr, replace head_ref) so workflows create stable, per-PR concurrency groups. This prevents runs for different pull requests (or branches with the same name) from canceling each other. Applied to ansible-test-windows.yml, ansible-test.yml, docs-pr.yml, and zizmor.yml. --- .github/workflows/ansible-test-windows.yml | 2 +- .github/workflows/ansible-test.yml | 2 +- .github/workflows/docs-pr.yml | 2 +- .github/workflows/zizmor.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ansible-test-windows.yml b/.github/workflows/ansible-test-windows.yml index ac4a6ae1..e9e79e8c 100644 --- a/.github/workflows/ansible-test-windows.yml +++ b/.github/workflows/ansible-test-windows.yml @@ -24,7 +24,7 @@ on: # Cancel existing runs on new commits to a branch concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true # Deny all permissions at workflow level - scope per job diff --git a/.github/workflows/ansible-test.yml b/.github/workflows/ansible-test.yml index ed876190..a329b305 100644 --- a/.github/workflows/ansible-test.yml +++ b/.github/workflows/ansible-test.yml @@ -32,7 +32,7 @@ on: # Cancel existing runs on new commits to a branch concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true # Deny all permissions at workflow level - scope per job diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index c45afc6d..ee73e862 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -1,6 +1,6 @@ name: Collection Docs concurrency: - group: docs-pr-${{ github.head_ref }} + group: docs-pr-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true on: pull_request: diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index b17afef1..8de0390b 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -5,7 +5,7 @@ on: branches: ["**"] concurrency: - group: ${{ github.workflow }}-${{ github.ref }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true permissions: {} From 77bdbf1f1b30542c25d64bf12e8985b00fb2671b Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 11 Apr 2026 14:08:19 -0400 Subject: [PATCH 9/9] Update docs-pr.yml --- .github/workflows/docs-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index ee73e862..6c1fb02c 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -3,7 +3,7 @@ concurrency: group: docs-pr-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true on: - pull_request: + pull_request_target: # zizmor: ignore[dangerous-triggers] -- pull_request_target is required to have permissions to comment on PRs from forks types: [opened, synchronize, reopened, closed] env: