Skip to content
Open
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
4 changes: 4 additions & 0 deletions .github/workflows/auto-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ concurrency:

jobs:
call-valtown:
# Guard: this workflow forwards merged PR metadata to an external webhook
# and only makes sense for the canonical repo. A fork with Actions enabled
# would otherwise attempt the same job and fail on missing repo secrets.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ubuntu-latest
timeout-minutes: 5

Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/bump-openclaw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ permissions:

jobs:
check:
# Guard: this workflow acts on shared state (the OpenClaw release webhook,
# which edits the KiloClaw Dockerfile and opens a bump PR) and only makes
# sense for the canonical repo. A fork with Actions enabled would otherwise
# attempt the same job and fail on missing repo secrets/vars.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 10
steps:
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/check-md-table-padding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ on:
jobs:
check:
name: Check markdown table padding
# Guard: a manual dispatch from a fork would otherwise run this check
# against the fork's own files. For pull_request events github.repository is
# already the base repo, so the guard is a no-op there and only blocks the
# fork-triggerable path.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ permissions:
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Guard: a fork with Actions enabled can trigger this workflow_dispatch,
# and CodeQL would run against the fork's own code with the fork's
# security-events scope. Only the canonical repo needs this analysis.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 30
strategy:
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/deploy-kiloclaw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ permissions:

jobs:
deploy:
# Guard: this workflow_dispatch is reachable from a fork, and it builds and
# pushes a container image to Fly and GHCR using repo secrets. Only the
# canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 30
name: Deploy KiloClaw
Expand Down Expand Up @@ -266,7 +270,7 @@ jobs:
# when its content was last built, so we don't pull a large unchanged image.
attest-sbom:
needs: deploy
if: needs.deploy.outputs.image-built == 'true' && needs.deploy.outputs.image-digest != ''
if: needs.deploy.outputs.image-built == 'true' && needs.deploy.outputs.image-digest != '' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
name: Attest image SBOM
Expand Down Expand Up @@ -306,6 +310,7 @@ jobs:
# continue-on-error ensures a dev push failure never blocks prod.
push-dev-image:
needs: [deploy]
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 10
name: Push Dev Image
Expand Down
27 changes: 21 additions & 6 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ env:

jobs:
check-changes:
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud'
uses: ./.github/workflows/check-deployment-changes.yml
with:
workflow_file: deploy-production.yml

check-production-db-startup:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: `schedule` and `workflow_dispatch` are reachable from a fork, so
# this is a real fork block. It is applied to every job so the workflow
Comment thread
maphew marked this conversation as resolved.
# cannot run outside the canonical repo under any path.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
environment: production
Expand Down Expand Up @@ -59,7 +64,8 @@ jobs:

run-migrations:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
environment: production
Expand Down Expand Up @@ -92,7 +98,8 @@ jobs:

stage-app:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
uses: ./.github/workflows/stage-vercel-deployment.yml
with:
target_environment: production
Expand All @@ -103,7 +110,8 @@ jobs:

stage-ai-gateway:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
uses: ./.github/workflows/stage-vercel-deployment.yml
with:
target_environment: production
Expand All @@ -114,6 +122,7 @@ jobs:

promote-app:
needs: [stage-app, check-production-db-startup, run-migrations]
if: github.repository == 'Kilo-Org/cloud'
uses: ./.github/workflows/promote-vercel-deployment.yml
with:
deployment_url: ${{ needs.stage-app.outputs.deployment_url }}
Expand All @@ -124,6 +133,8 @@ jobs:

promote-ai-gateway:
needs: [stage-ai-gateway, check-production-db-startup, run-migrations]
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud'
uses: ./.github/workflows/promote-vercel-deployment.yml
with:
deployment_url: ${{ needs.stage-ai-gateway.outputs.deployment_url }}
Expand All @@ -149,6 +160,7 @@ jobs:
]
if: >-
${{
github.repository == 'Kilo-Org/cloud' &&
!cancelled() &&
needs.check-changes.outputs.should_deploy == 'true' &&
needs.check-production-db-startup.result == 'success' &&
Expand All @@ -168,7 +180,7 @@ jobs:
# successful worker deploy and releases only when the kilo-mcp bundle changed.
kilo-mcp-release:
needs: [check-changes, deploy-workers]
if: ${{ !cancelled() && needs.deploy-workers.result == 'success' }}
if: ${{ github.repository == 'Kilo-Org/cloud' && !cancelled() && needs.deploy-workers.result == 'success' }}
# Ceiling for the reusable workflow's GITHUB_TOKEN (a called workflow cannot
# exceed the caller).
permissions:
Expand All @@ -182,7 +194,8 @@ jobs:

detect-gastown-wasteland-changes:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 5
outputs:
Expand Down Expand Up @@ -255,6 +268,7 @@ jobs:
]
if: >-
${{
github.repository == 'Kilo-Org/cloud' &&
!cancelled() &&
needs.check-changes.outputs.should_deploy == 'true' &&
needs.check-production-db-startup.result == 'success' &&
Expand Down Expand Up @@ -332,6 +346,7 @@ jobs:
]
if: >-
${{
github.repository == 'Kilo-Org/cloud' &&
!cancelled() &&
needs.check-changes.outputs.should_deploy == 'true' &&
needs.check-production-db-startup.result == 'success' &&
Expand Down
15 changes: 11 additions & 4 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ jobs:

check-staging-db-startup:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: this workflow_dispatch is reachable from a fork, and it deploys
# the web app to staging using repo secrets. Only the canonical repo may
# run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
environment: staging
Expand Down Expand Up @@ -55,7 +58,8 @@ jobs:

run-migrations:
needs: check-changes
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
environment: staging
Expand Down Expand Up @@ -88,7 +92,8 @@ jobs:

deploy-app:
needs: [check-changes, check-staging-db-startup, run-migrations]
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
uses: ./.github/workflows/stage-vercel-deployment.yml
with:
target_environment: staging
Expand All @@ -99,7 +104,8 @@ jobs:

deploy-ai-gateway:
needs: [check-changes, check-staging-db-startup, run-migrations]
if: needs.check-changes.outputs.should_deploy == 'true'
# Guard: privileged workflow — only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud' && needs.check-changes.outputs.should_deploy == 'true'
uses: ./.github/workflows/stage-vercel-deployment.yml
with:
target_environment: staging
Expand Down Expand Up @@ -130,6 +136,7 @@ jobs:
]
if: >-
${{
github.repository == 'Kilo-Org/cloud' &&
!cancelled() &&
needs.check-changes.outputs.should_deploy == 'true' &&
needs.check-staging-db-startup.result == 'success' &&
Expand Down
11 changes: 8 additions & 3 deletions .github/workflows/deploy-workers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,11 @@ concurrency:

jobs:
deploy-manual:
if: inputs.worker != ''
# Guard: this workflow_dispatch is reachable from a fork, and it deploys
# Cloudflare Workers using repo secrets. Only the canonical repo may run
# it. (Also called as a reusable workflow from deploy-staging.yml, whose
# caller job is itself guarded.)
if: inputs.worker != '' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: ${{ inputs.worker == 'services/cloud-agent-next' && 75 || inputs.worker == 'services/auto-routing-benchmark' && inputs.target_environment == 'production' && 60 || 25 }}
name: Deploy ${{ inputs.worker }}
Expand Down Expand Up @@ -148,7 +152,8 @@ jobs:
command: ${{ steps.runtime.outputs.command || (inputs.target_environment == 'production' && 'deploy' || format('deploy --env {0}', inputs.target_environment)) }}

detect-changes:
if: inputs.worker == '' && inputs.base_sha != ''
# Guard: privileged workflow — only the canonical repo may run it.
if: inputs.worker == '' && inputs.base_sha != '' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 5
outputs:
Expand Down Expand Up @@ -314,7 +319,7 @@ jobs:

deploy-changed:
needs: detect-changes
if: needs.detect-changes.outputs.matrix != '[]' && needs.detect-changes.outputs.matrix != ''
if: needs.detect-changes.outputs.matrix != '[]' && needs.detect-changes.outputs.matrix != '' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: ${{ matrix.worker == 'services/cloud-agent-next' && 75 || matrix.worker == 'services/auto-routing-benchmark' && inputs.target_environment == 'production' && 60 || 25 }}
environment: ${{ inputs.target_environment }}
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/extension-store-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ permissions:

jobs:
build-artifacts:
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 30
env:
Expand Down Expand Up @@ -86,8 +87,9 @@ jobs:
bump-version:
needs: build-artifacts
# Only a main dispatch bumps: a branch dispatch would open a PR carrying
# unrelated commits.
if: github.ref == 'refs/heads/main'
# unrelated commits. Also guarded to the canonical repo: a fork dispatch
# would otherwise push a bump branch and open a PR against the fork.
if: github.ref == 'refs/heads/main' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
Expand Down
15 changes: 10 additions & 5 deletions .github/workflows/kilo-app-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ permissions:

jobs:
check-changes:
# Guard: this workflow_dispatch/schedule is reachable from a fork, and it
# submits a mobile build to the App Store / Google Play using repo secrets.
# Only the canonical repo may run it. (For push: main, github.repository is
# already the canonical repo, so the guard is a no-op there.)
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 5
permissions:
Expand Down Expand Up @@ -153,12 +158,12 @@ jobs:

validate:
needs: [check-changes]
if: needs.check-changes.outputs.should_build == 'true' && needs.check-changes.outputs.allowed == 'true'
if: needs.check-changes.outputs.should_build == 'true' && needs.check-changes.outputs.allowed == 'true' && github.repository == 'Kilo-Org/cloud'
uses: ./.github/workflows/kilo-app-ci.yml

preflight:
needs: [check-changes]
if: needs.check-changes.outputs.should_build == 'true' && github.ref == 'refs/heads/main' && needs.check-changes.outputs.allowed == 'true'
if: needs.check-changes.outputs.should_build == 'true' && github.ref == 'refs/heads/main' && needs.check-changes.outputs.allowed == 'true' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
permissions:
Expand Down Expand Up @@ -223,7 +228,7 @@ jobs:

build-and-submit:
needs: [check-changes, validate, preflight]
if: needs.check-changes.outputs.should_build == 'true' && github.ref == 'refs/heads/main' && needs.check-changes.outputs.allowed == 'true'
if: needs.check-changes.outputs.should_build == 'true' && github.ref == 'refs/heads/main' && needs.check-changes.outputs.allowed == 'true' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 60
outputs:
Expand Down Expand Up @@ -470,7 +475,7 @@ jobs:
# the section lands, which loses the build's changelog line for ever.
bump-version:
needs: [check-changes]
if: needs.check-changes.outputs.should_build == 'true' && github.ref == 'refs/heads/main' && needs.check-changes.outputs.allowed == 'true'
if: needs.check-changes.outputs.should_build == 'true' && github.ref == 'refs/heads/main' && needs.check-changes.outputs.allowed == 'true' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
Expand Down Expand Up @@ -556,7 +561,7 @@ jobs:
# build writes it above its own section.
changelog:
needs: [check-changes, bump-version, build-and-submit]
if: needs.check-changes.outputs.should_build == 'true' && needs.check-changes.outputs.allowed == 'true' && github.ref == 'refs/heads/main'
if: needs.check-changes.outputs.should_build == 'true' && needs.check-changes.outputs.allowed == 'true' && github.ref == 'refs/heads/main' && github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 10
permissions:
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/promote-vercel-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ permissions:

jobs:
promote:
# Guard: this reusable workflow promotes a Vercel deployment to production
# using repo secrets. It is only ever called by guarded caller jobs, but
# the guard is also applied here so the workflow cannot run outside the
# canonical repo even if a caller skips its own guard.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 15
environment: production
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/push-dev-kiloclaw.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ permissions:

jobs:
push-dev:
# Guard: this workflow_dispatch builds and pushes a container image to
# Fly and GHCR using repo secrets. Only the canonical repo may run it.
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 30
name: Build & Push Dev Image
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/redeploy-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ concurrency:

jobs:
verify-main:
# Guard: this workflow_dispatch is reachable from a fork, and it deploys
# the web app to production using repo secrets. Only the canonical repo
# may run it. (verify-main already enforces GITHUB_REF == refs/heads/main,
# so the guard is defense-in-depth for the dispatch path.)
if: github.repository == 'Kilo-Org/cloud'
runs-on: ${{ vars.RUNNER_DEFAULT_LABEL || 'ubuntu-latest' }}
timeout-minutes: 5

Expand All @@ -25,6 +30,7 @@ jobs:

stage-app:
needs: verify-main
if: github.repository == 'Kilo-Org/cloud'
uses: ./.github/workflows/stage-vercel-deployment.yml
with:
target_environment: production
Expand All @@ -34,6 +40,7 @@ jobs:

promote-app:
needs: stage-app
if: github.repository == 'Kilo-Org/cloud'
uses: ./.github/workflows/promote-vercel-deployment.yml
with:
deployment_url: ${{ needs.stage-app.outputs.deployment_url }}
Expand Down
Loading