Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 46 additions & 30 deletions .github/workflows/package-image-row.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,20 @@ jobs:
permissions:
contents: read
id-token: write
runs-on: ${{ fromJSON(fromJSON(inputs.row_json).runner_labels) }}
runs-on: >-
${{
vars.DEPOT_REGISTRY_CACHE_ENABLED == 'true'
&& github.repository == 'Mesh-LLM/mesh-packaging'
&& github.ref == 'refs/heads/main'
&& github.workflow_ref == 'Mesh-LLM/mesh-packaging/.github/workflows/images-release.yml@refs/heads/main'
&& (github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
&& (
fromJSON(inputs.row_json).arch == 'arm64'
&& 'depot-ubuntu-24.04-arm'
|| 'depot-ubuntu-24.04'
)
|| fromJSON(fromJSON(inputs.row_json).runner_labels)
}}
outputs:
package_base_image: ${{ steps.bases.outputs.package_base_image }}
runtime_base_image: ${{ steps.bases.outputs.runtime_base_image }}
Expand Down Expand Up @@ -92,6 +105,10 @@ jobs:
"$REPOSITORY" == Mesh-LLM/mesh-packaging &&
"$WORKFLOW_SOURCE_REF" == refs/heads/main &&
"$WORKFLOW_REF" == Mesh-LLM/mesh-packaging/.github/workflows/images-release.yml@refs/heads/main ]]; then
[[ "${DEPOT_ORG_ID:-}" == 1ntz5vlngn ]] || {
echo "pull-through bases require a pre-authenticated Depot runner" >&2
exit 1
}
case "$EVENT_NAME" in
repository_dispatch|workflow_dispatch) ;;
*) echo "pull-through bases rejected event: $EVENT_NAME" >&2; exit 1 ;;
Expand All @@ -118,15 +135,6 @@ jobs:
echo "registry_cache_selected=$registry_cache_selected"
echo "depot_registry_host=$depot_registry_host"
} >> "$GITHUB_OUTPUT"
- name: Authenticate pull-through base images
if: steps.bases.outputs.registry_cache_selected == 'true'
env:
DEPOT_REGISTRY_HOST: ${{ steps.bases.outputs.depot_registry_host }}
shell: bash
run: |
set -euo pipefail
depot pull-token --project "$DEPOT_PROJECT_ID" |
docker login "$DEPOT_REGISTRY_HOST" --username x-token --password-stdin
- name: Verify exact pull-through base manifests
if: steps.bases.outputs.registry_cache_selected == 'true'
env:
Expand Down Expand Up @@ -258,7 +266,20 @@ jobs:
permissions:
contents: read
id-token: write
runs-on: ${{ fromJSON(fromJSON(inputs.row_json).runner_labels) }}
runs-on: >-
${{
vars.DEPOT_REGISTRY_CACHE_ENABLED == 'true'
&& github.repository == 'Mesh-LLM/mesh-packaging'
&& github.ref == 'refs/heads/main'
&& github.workflow_ref == 'Mesh-LLM/mesh-packaging/.github/workflows/images-release.yml@refs/heads/main'
&& (github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
&& (
fromJSON(inputs.row_json).arch == 'arm64'
&& 'depot-ubuntu-24.04-arm'
|| 'depot-ubuntu-24.04'
)
|| fromJSON(fromJSON(inputs.row_json).runner_labels)
}}
Comment on lines +269 to +282

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
git ls-files | rg '(^|/)\package-image-row\.ya?ml$|(^|/)\package-image-row\.ya?ml$' || true

echo "== file lines around concern =="
if [ -f .github/workflows/package-image-row.yml ]; then
  wc -l .github/workflows/package-image-row.yml
  sed -n '230,320p' .github/workflows/package-image-row.yml
  echo "== lines around 340-405 =="
  sed -n '340,410p' .github/workflows/package-image-row.yml
fi

echo "== DEPOT_ORG_ID and registry cache references =="
rg -n "DEPOT_ORG_ID|DEPOT_REGISTRY_CACHE_ENABLED|registry_cache_selected|runtime_base_image|dry-image|stage-image|packages: write|attestations: write" .github/workflows/package-image-row.yml .github/workflows || true

echo "== workflow jobs overview =="
python3 - <<'PY'
from pathlib import Path
p=Path(".github/workflows/package-image-row.yml")
if p.exists():
    text=p.read_text()
    lines=text.splitlines()
    in_jobs=False
    for i,l in enumerate(lines,1):
        if l.rstrip()=="jobs:":
            in_jobs=True
            continue
        if in_jobs and l and not l.startswith(" ") and not l.startswith("\t") and l.endswith(":"):
            job=l.rstrip().rstrip(":")
            print(f"{i}: job={job}")
            # print next 40 lines indented for job
            for j in range(i+1, min(len(lines), i+70)+1):
                print(f"  {j}: {lines[j-1]}")
                if lines[j-1].rstrip() and not lines[j-1].startswith(" ") and not lines[j-1].startswith("\t") and j>i+1:
                    break
PY

Repository: Mesh-LLM/mesh-packaging

Length of output: 15103


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== deps package job =="
sed -n '1,160p' .github/workflows/package-image-row.yml

echo "== dry-image remaining steps =="
sed -n '300,345p' .github/workflows/package-image-row.yml

echo "== stage-image full step block =="
sed -n '420,530p' .github/workflows/package-image-row.yml

echo "== all Depot steps and RUNTIME_BASE_IMAGE usage =="
python3 - <<'PY'
from pathlib import Path
for path in [Path(".github/workflows/package-image-row.yml"), Path(".github/workflows/images-release.yml")]:
    if not path.exists():
        continue
    lines=path.read_text().splitlines()
    print(f"FILE {path}")
    for i,l in enumerate(lines,1):
        if "depot/" in l or "RUNTIME_BASE_IMAGE" in l or "runtime_base_image" in l or "DEPOT_ORG_ID" in l or "registry_cache_selected" in l:
            start=max(1,i-5); end=min(len(lines),i+8)
            print(f"-- around line {i} --")
            for j in range(start,end+1):
                print(f"{j}: {lines[j-1]}")
PY

echo "== repo dependency files =="
git ls-files | rg '(^|/)(package(-lock)?\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?|tsconfig\.json)$|\.gitmodules$' || true

Repository: Mesh-LLM/mesh-packaging

Length of output: 41026


🌐 Web query:

Depot GitHub Actions runners assigned per job workflow DEPOT_ORG_ID documentation

💡 Result:

In Depot GitHub Actions runners, the DEPOT_ORG_ID is automatically set and managed by the system for jobs running on Depot infrastructure [1]. You do not need to manually assign or configure this environment variable in your GitHub Actions workflow file to "assign" a job to a Depot runner [2][3]. To use Depot runners, you simply change the runs-on label in your workflow YAML file to the appropriate Depot-provided label (e.g., runs-on: depot-ubuntu-24.04) [4][2][5]. Key points regarding DEPOT_ORG_ID and Depot Runners: * Automatic Configuration: When a job runs on a Depot GitHub Actions runner, the runner environment is pre-configured with necessary variables, including DEPOT_ORG_ID, automatically [1]. * Usage: DEPOT_ORG_ID is primarily used by the infrastructure to provide context for services like Depot Cache, Turborepo remote caching, or when using specific CLI tools that require identification of the organization [1][6][7][8]. * Manual Assignment: Manual configuration of DEPOT_ORG_ID is generally not required for standard runner operation [2]. If you are using specific integrations—such as configuring local cache tools like Gradle, Bazel, or sccache outside of the automatically configured runner environment—you might need to reference the DEPOT_ORG_ID, which can be found in your Depot dashboard under organization settings [6][7][8]. * Workflow Setup: To enable the runners, you connect your GitHub organization to Depot via the Depot dashboard and install the Depot GitHub App [4][5][3]. Once connected, the runner infrastructure handles the registration and job execution dynamically [3]. For detailed configuration of runner sizes or specific OS types, you should use the designated single-label format, such as depot-ubuntu-24.04-4, rather than attempting to inject organization identifiers manually [5].

Citations:


Add a Depot runner identity check to the image jobs when using pull-through cache.

deps checks DEPOT_ORG_ID, but Depot runners are selected per job and dry-image / stage-image also select Depot runners independently. Gate the check on needs.package.outputs.registry_cache_selected == 'true' and fail closed before either job starts the registry/cache-dependent depot/build-push-action so later jobs cannot use cached bases from an unexpected runner.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/package-image-row.yml around lines 269 - 282, Add the
Depot runner identity validation to both the dry-image and stage-image jobs
before their registry/cache-dependent depot/build-push-action steps, and gate it
on needs.package.outputs.registry_cache_selected == 'true'. Reuse the existing
DEPOT_ORG_ID check from deps, fail closed on a mismatch, and ensure the
validation runs before either job can access cached bases.

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
Expand All @@ -271,15 +292,6 @@ jobs:
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1
with:
version: 2.101.77
- name: Authenticate pull-through runtime base
if: needs.package.outputs.registry_cache_selected == 'true'
env:
DEPOT_REGISTRY_HOST: ${{ needs.package.outputs.depot_registry_host }}
shell: bash
run: |
set -euo pipefail
depot pull-token --project "$DEPOT_PROJECT_ID" |
docker login "$DEPOT_REGISTRY_HOST" --username x-token --password-stdin
- name: Read immutable product inputs
id: product
shell: bash
Expand Down Expand Up @@ -358,7 +370,20 @@ jobs:
name: Stage and test exact registry digest
if: ${{ inputs.publish_images }}
needs: package
runs-on: ${{ fromJSON(fromJSON(inputs.row_json).runner_labels) }}
runs-on: >-
${{
vars.DEPOT_REGISTRY_CACHE_ENABLED == 'true'
&& github.repository == 'Mesh-LLM/mesh-packaging'
&& github.ref == 'refs/heads/main'
&& github.workflow_ref == 'Mesh-LLM/mesh-packaging/.github/workflows/images-release.yml@refs/heads/main'
&& (github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
&& (
fromJSON(inputs.row_json).arch == 'arm64'
&& 'depot-ubuntu-24.04-arm'
|| 'depot-ubuntu-24.04'
)
|| fromJSON(fromJSON(inputs.row_json).runner_labels)
}}
environment: release
permissions:
contents: read
Expand All @@ -377,15 +402,6 @@ jobs:
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1
with:
version: 2.101.77
- name: Authenticate pull-through runtime base
if: needs.package.outputs.registry_cache_selected == 'true'
env:
DEPOT_REGISTRY_HOST: ${{ needs.package.outputs.depot_registry_host }}
shell: bash
run: |
set -euo pipefail
depot pull-token --project "$DEPOT_PROJECT_ID" |
docker login "$DEPOT_REGISTRY_HOST" --username x-token --password-stdin
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
Expand Down
10 changes: 6 additions & 4 deletions docs/publishing.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,12 @@ After every enabled mapping meets the threshold, set
`DEPOT_REGISTRY_HOST` to the organization host ending in
`.registry.depot.dev`, then set `DEPOT_REGISTRY_CACHE_ENABLED=true`. The reusable
row workflow selects mirrors only for exact `main` executions of the canonical
release caller and obtains a short-lived read-only pull token through GitHub
OIDC. No long-lived registry secret is required. It resolves public references
first, retains their exact digest in the Depot reference, and verifies the
mirrored manifest before building.
release caller and routes those jobs to Depot Actions runners. Depot
pre-authenticates each runner to pull organization Registry images with a
short-lived job credential; no long-lived registry secret is required. The
workflow verifies the injected Depot organization identity, resolves public
references first, retains their exact digest in the Depot reference, and
verifies the mirrored manifest before building.

This cache can reduce cold base pulls and public-registry rate-limit delays. It
does not accelerate apt, Cargo, pnpm/npm, native compilation, or Docker layer
Expand Down
13 changes: 9 additions & 4 deletions tests/release-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,18 @@ test("pull-through bases are opt-in, trusted, digest-pinned, and short-lived", (
assert.match(packageJob, /package_base_image="\$DEPOT_REGISTRY_HOST\/\$PACKAGE_CACHE_REPOSITORY@\$\{package_base_image##\*@\}"/);
assert.match(packageJob, /runtime_base_image="\$DEPOT_REGISTRY_HOST\/\$RUNTIME_CACHE_REPOSITORY@\$\{runtime_base_image##\*@\}"/);
assert.match(packageJob, /Verify exact pull-through base manifests/);
assert.match(packageJob, /pull-through bases require a pre-authenticated Depot runner/);

for (const job of [packageJob, dry, stage]) {
assert.match(job, /depot pull-token --project "\$DEPOT_PROJECT_ID"/);
assert.match(job, /docker login "\$DEPOT_REGISTRY_HOST" --username x-token --password-stdin/);
assert.match(job, /vars\.DEPOT_REGISTRY_CACHE_ENABLED == 'true'/);
assert.match(job, /github\.repository == 'Mesh-LLM\/mesh-packaging'/);
assert.match(job, /github\.ref == 'refs\/heads\/main'/);
assert.match(job, /github\.workflow_ref == 'Mesh-LLM\/mesh-packaging\/\.github\/workflows\/images-release\.yml@refs\/heads\/main'/);
assert.match(job, /github\.event_name == 'workflow_dispatch'/);
assert.match(job, /github\.event_name == 'repository_dispatch'/);
assert.match(job, /depot-ubuntu-24\.04/);
}
assert.equal(row.split("depot pull-token --project").length - 1, 3);
assert.doesNotMatch(row, /DEPOT_REGISTRY_PULL_TOKEN|secrets\.DEPOT|DEPOT_TOKEN/);
assert.doesNotMatch(row, /depot pull-token|docker login "\$DEPOT_REGISTRY_HOST"|DEPOT_REGISTRY_PULL_TOKEN|secrets\.DEPOT|DEPOT_TOKEN/);
assert.match(dry, /RUNTIME_BASE_IMAGE=\$\{\{ needs\.package\.outputs\.runtime_base_image \}\}/);
assert.match(stage, /RUNTIME_BASE_IMAGE=\$\{\{ needs\.package\.outputs\.runtime_base_image \}\}/);
});
Expand Down