fix(ci): authenticate docker so cosign can sign the published chart #75
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # Repo-wide linting and link-check. | |
| # | |
| # This workflow has NO path filter — it runs on every pull_request and | |
| # every push to main. That guarantees a `ci-gate` check is always posted | |
| # on a PR, even doc-only or label-only changes that wouldn't otherwise | |
| # trigger operator-ci or agent-ci. operator-ci and agent-ci also publish | |
| # checks named `ci-gate`; GitHub composes same-named required checks so | |
| # every ci-gate that posts must pass. | |
| name: Lint CI | |
| on: | |
| workflow_dispatch: {} | |
| pull_request: {} | |
| push: | |
| branches: | |
| - main | |
| env: | |
| # Opt all JS actions into Node 24 ahead of GitHub's Node 20 phase-out. | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| # Pin third-party tooling versions and binary checksums. NVIDIA's enterprise | |
| # restricts which GitHub Actions can be used, so actionlint and lychee are | |
| # installed as binaries directly rather than via wrapper actions; SHA256 | |
| # pins protect against tarball replacement on the upstream release. | |
| ACTIONLINT_VERSION: 1.7.7 | |
| ACTIONLINT_SHA256: 023070a287cd8cccd71515fedc843f1985bf96c436b7effaecce67290e7e0757 | |
| LYCHEE_VERSION: 0.21.0 | |
| LYCHEE_SHA256: a06547250f10021dcafc6ed5bb20fca75835b65711745b63cfdda34c29ff6a73 | |
| YAMLLINT_VERSION: 1.38.0 | |
| jobs: | |
| meta-lint: | |
| name: meta-lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: actionlint (workflow files) | |
| if: always() | |
| run: | | |
| set -euo pipefail | |
| curl -sSfL "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" -o /tmp/actionlint.tgz | |
| echo "${ACTIONLINT_SHA256} /tmp/actionlint.tgz" | sha256sum -c - | |
| tar -xzf /tmp/actionlint.tgz -C /tmp actionlint | |
| # -shellcheck= disables the shellcheck integration. Existing | |
| # workflows have many SC2086/SC2155/etc. warnings that are | |
| # tracked separately; this PR's scope is structural lint only. | |
| /tmp/actionlint -color -shellcheck= | |
| - name: yamllint | |
| if: always() | |
| run: | | |
| pip install --user --quiet "yamllint==${YAMLLINT_VERSION}" | |
| yamllint -c ci/yamllint.yaml . | |
| - name: markdownlint | |
| if: always() | |
| # SHA pinned to satisfy NVIDIA's enterprise allow-list. | |
| uses: DavidAnson/markdownlint-cli2-action@07035fd053f7be764496c0f8d8f9f41f98305101 | |
| with: | |
| config: ci/.markdownlint-cli2.yaml | |
| globs: | | |
| **/*.md | |
| !**/vendor/** | |
| !**/node_modules/** | |
| # Generated by 'make notices'; license texts contain formatting | |
| # we don't control (multiple blanks, etc.). Even with the generator's | |
| # blank-collapse step the per-license bodies vary widely. | |
| !THIRD_PARTY_NOTICES.md | |
| !agent/THIRD_PARTY_NOTICES.md | |
| !operator/THIRD_PARTY_NOTICES.md | |
| # Generated by git-cliff on every release; format intrinsically | |
| # violates MD032/MD024/MD009. Track separately if changelog | |
| # style ever needs enforcement. | |
| !**/CHANGELOG.md | |
| # NVIDIA-managed template; not for us to lint. | |
| !SECURITY.md | |
| - name: Install lychee | |
| if: always() | |
| run: | | |
| set -euo pipefail | |
| curl -sSfL "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE_VERSION}/lychee-x86_64-unknown-linux-gnu.tar.gz" -o /tmp/lychee.tgz | |
| echo "${LYCHEE_SHA256} /tmp/lychee.tgz" | sha256sum -c - | |
| tar -xzf /tmp/lychee.tgz -C /tmp lychee | |
| # Persist lychee's URL cache across runs so transient external | |
| # failures don't re-fail every PR. Cache is keyed weekly so dead | |
| # links still surface within ~7 days. | |
| - name: Restore lychee cache | |
| if: always() | |
| uses: actions/cache@v4 | |
| with: | |
| path: .lycheecache | |
| key: lychee-${{ github.run_id }} | |
| restore-keys: | | |
| lychee- | |
| # Pass 1: internal links only (relative paths, anchors, file://). | |
| # These can never be flaky — if this fails, the PR really did break | |
| # a link. --offline tells lychee to skip http(s) entirely. | |
| - name: lychee — internal links (blocking) | |
| if: always() | |
| run: | | |
| /tmp/lychee \ | |
| --no-progress \ | |
| --offline \ | |
| --exclude-file ci/lycheeignore \ | |
| --exclude-path THIRD_PARTY_NOTICES.md \ | |
| --exclude-path agent/THIRD_PARTY_NOTICES.md \ | |
| --exclude-path agent/vendor \ | |
| --exclude-path operator/THIRD_PARTY_NOTICES.md \ | |
| --exclude-path operator/vendor \ | |
| './**/*.md' | |
| # Pass 2: external links. Non-blocking — a `kubernetes.io` blip or | |
| # GitHub rate-limit shouldn't block a docs PR. 4xx/5xx/429 are | |
| # accepted as "not definitively broken" since they're commonly | |
| # transient. Real dead links surface as ❌ in the step log; ci-gate | |
| # below ignores this step's result. | |
| - name: lychee — external links (advisory) | |
| if: always() | |
| continue-on-error: true | |
| # `--retry-wait-time 5` is a constant minimum delay between retries | |
| # (exponential backoff in lychee is reserved for HTTP 429); with | |
| # `--max-retries 8` that's roughly 8×5s = 40s per failing URL. The | |
| # step timeout is a runaway guard for the case where many URLs all | |
| # retry concurrently and/or are stuck timing out at `--timeout 20`. | |
| timeout-minutes: 15 | |
| env: | |
| # GitHub token avoids unauthenticated rate-limiting on github.com URLs. | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| /tmp/lychee \ | |
| --no-progress \ | |
| --cache \ | |
| --max-cache-age 7d \ | |
| --max-retries 8 \ | |
| --retry-wait-time 5 \ | |
| --timeout 20 \ | |
| --accept "200..=299,403,429,500..=599" \ | |
| --exclude-file ci/lycheeignore \ | |
| --exclude-path THIRD_PARTY_NOTICES.md \ | |
| --exclude-path agent/THIRD_PARTY_NOTICES.md \ | |
| --exclude-path agent/vendor \ | |
| --exclude-path operator/THIRD_PARTY_NOTICES.md \ | |
| --exclude-path operator/vendor \ | |
| './**/*.md' | |
| # See operator-ci.yaml's ci-gate for rationale. | |
| ci-gate: | |
| name: ci-gate | |
| needs: [meta-lint] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify all required jobs passed | |
| run: | | |
| results='${{ toJSON(needs) }}' | |
| echo "$results" | |
| echo "$results" | jq -e 'to_entries | all(.value.result == "success")' |