Skip to content
This repository was archived by the owner on Jun 14, 2026. It is now read-only.

[🛡️ MCP Host Validation | Part 1] MCP host allow-list #56

[🛡️ MCP Host Validation | Part 1] MCP host allow-list

[🛡️ MCP Host Validation | Part 1] MCP host allow-list #56

Workflow file for this run

name: PR
on:
pull_request:
branches: [ main ]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
actions: read
jobs:
prepare:
name: Prepare
runs-on: ubuntu-24.04-arm
timeout-minutes: 5
outputs:
# Per-surface filter outputs, passed as `with:` inputs to reusables.
rust: ${{ steps.filter.outputs.rust }}
ts: ${{ steps.filter.outputs.ts }}
landing: ${{ steps.filter.outputs.landing }}
web: ${{ steps.filter.outputs.web }}
api: ${{ steps.filter.outputs.api }}
embedding: ${{ steps.filter.outputs.embedding }}
docker: ${{ steps.filter.outputs.docker }}
actions: ${{ steps.filter.outputs.actions }}
workflows_lint: ${{ steps.filter.outputs.workflows_lint }}
workflows_type_check: ${{ steps.filter.outputs.workflows_type_check }}
workflows_unit_test: ${{ steps.filter.outputs.workflows_unit_test }}
workflows_integration_test: ${{ steps.filter.outputs.workflows_integration_test }}
workflows_security_audit: ${{ steps.filter.outputs.workflows_security_audit }}
workflows_lhci: ${{ steps.filter.outputs.workflows_lhci }}
workflows_docker_build: ${{ steps.filter.outputs.workflows_docker_build }}
workflows_e2e_test: ${{ steps.filter.outputs.workflows_e2e_test }}
terraform: ${{ steps.filter.outputs.terraform }}
shell: ${{ steps.filter.outputs.shell }}
markdown: ${{ steps.filter.outputs.markdown }}
openapi: ${{ steps.filter.outputs.openapi }}
astro: ${{ steps.filter.outputs.astro }}
claude_plugin: ${{ steps.filter.outputs.claude_plugin }}
lint_needed: ${{ steps.filter.outputs.rust == 'true' || steps.filter.outputs.ts == 'true' || steps.filter.outputs.shell == 'true' || steps.filter.outputs.markdown == 'true' || steps.filter.outputs.terraform == 'true' || steps.filter.outputs.astro == 'true' || steps.filter.outputs.openapi == 'true' || steps.filter.outputs.claude_plugin == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_lint == 'true' }}
type_check_needed: ${{ steps.filter.outputs.ts == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_type_check == 'true' }}
unit_test_needed: ${{ steps.filter.outputs.rust == 'true' || steps.filter.outputs.ts == 'true' || steps.filter.outputs.shell == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_unit_test == 'true' }}
integration_test_needed: ${{ steps.filter.outputs.rust == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_integration_test == 'true' }}
security_audit_needed: ${{ steps.filter.outputs.rust == 'true' || steps.filter.outputs.ts == 'true' || steps.filter.outputs.docker == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_security_audit == 'true' }}
lhci_needed: ${{ steps.filter.outputs.landing == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_lhci == 'true' }}
docker_build_needed: ${{ (steps.filter.outputs.rust == 'true' || steps.filter.outputs.ts == 'true' || steps.filter.outputs.docker == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_docker_build == 'true') && github.event.pull_request.head.repo.full_name == github.repository }}
e2e_test_needed: ${{ (steps.filter.outputs.rust == 'true' || steps.filter.outputs.ts == 'true' || steps.filter.outputs.docker == 'true' || steps.filter.outputs.actions == 'true' || steps.filter.outputs.workflows_e2e_test == 'true') && github.event.pull_request.head.repo.full_name == github.repository }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Per-surface inclusions
id: filter
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
with:
# dorny/paths-filter evaluates each list entry as an independent
# picomatch pattern and OR's the results, so a standalone negation
# like '!**/*.md' fires as a positive match on every non-`.md` file.
# Embed the negation as an extglob suffix on the parent path instead
# so it constrains that one pattern's filename match.
filters: |
rust:
- 'apps/api/**/!(*.md|*.mdx)'
- 'apps/embedding_service/**/!(*.md|*.mdx)'
- 'apps/so_tag_sync/**/!(*.md|*.mdx)'
- 'integrations/**'
- 'Cargo.toml'
- 'Cargo.lock'
ts:
- 'apps/web/**/!(*.md|*.mdx)'
- 'apps/landing/**/!(*.md|*.mdx)'
- 'packages/**/!(*.md|*.mdx)'
- 'apps/api/openapi.json'
- 'package.json'
- 'bun.lock'
- 'bunfig.toml'
- 'turbo.json'
landing:
- 'apps/landing/**/!(*.md|*.mdx)'
web:
- 'apps/web/**/!(*.md|*.mdx)'
api:
- 'apps/api/**/!(*.md|*.mdx)'
embedding:
- 'apps/embedding_service/**/!(*.md|*.mdx)'
docker:
- 'docker-compose.yml'
- 'apps/*/Dockerfile'
- 'infra/docker/**/!(*.md|*.mdx)'
actions:
- '.github/actions/**/!(*.md|*.mdx)'
workflows_lint:
- '.github/workflows/lint.yml'
workflows_type_check:
- '.github/workflows/type_check.yml'
workflows_unit_test:
- '.github/workflows/unit_test.yml'
workflows_integration_test:
- '.github/workflows/integration_test.yml'
workflows_security_audit:
- '.github/workflows/security_audit.yml'
workflows_lhci:
- '.github/workflows/lhci.yml'
workflows_docker_build:
- '.github/workflows/docker_build.yml'
workflows_e2e_test:
- '.github/workflows/e2e_test.yml'
terraform:
- 'terraform/**'
- '**/*.tf'
- '**/*.tftpl'
shell:
- '**/*.sh'
- 'scripts/**'
markdown:
- '**/*.md'
- '**/*.mdx'
openapi:
- 'apps/api/openapi.json'
astro:
- 'apps/landing/**/*.astro'
claude_plugin:
- '.claude-plugin/**'
- 'integrations/claude/**'
lint:
needs: prepare
if: needs.prepare.outputs.lint_needed == 'true'
uses: ./.github/workflows/lint.yml
with:
rust: ${{ needs.prepare.outputs.rust == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
ts: ${{ needs.prepare.outputs.ts == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
shell: ${{ needs.prepare.outputs.shell == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
markdown: ${{ needs.prepare.outputs.markdown == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
terraform: ${{ needs.prepare.outputs.terraform == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
astro: ${{ needs.prepare.outputs.astro == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
openapi: ${{ needs.prepare.outputs.openapi == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
claude_plugin: ${{ needs.prepare.outputs.claude_plugin == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_lint == 'true' }}
secrets: inherit
type_check:
needs: prepare
if: needs.prepare.outputs.type_check_needed == 'true'
uses: ./.github/workflows/type_check.yml
with:
ts: ${{ needs.prepare.outputs.ts == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_type_check == 'true' }}
secrets: inherit
unit_test:
needs: prepare
if: needs.prepare.outputs.unit_test_needed == 'true'
uses: ./.github/workflows/unit_test.yml
with:
rust: ${{ needs.prepare.outputs.rust == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_unit_test == 'true' }}
ts: ${{ needs.prepare.outputs.ts == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_unit_test == 'true' }}
shell: ${{ needs.prepare.outputs.shell == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_unit_test == 'true' }}
secrets: inherit
integration_test:
needs: prepare
if: needs.prepare.outputs.integration_test_needed == 'true'
uses: ./.github/workflows/integration_test.yml
with:
rust: ${{ needs.prepare.outputs.rust == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_integration_test == 'true' }}
secrets: inherit
security_audit:
needs: prepare
if: needs.prepare.outputs.security_audit_needed == 'true'
uses: ./.github/workflows/security_audit.yml
with:
rust: ${{ needs.prepare.outputs.rust == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_security_audit == 'true' }}
ts: ${{ needs.prepare.outputs.ts == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_security_audit == 'true' }}
docker: ${{ needs.prepare.outputs.docker == 'true' || needs.prepare.outputs.actions == 'true' || needs.prepare.outputs.workflows_security_audit == 'true' }}
secrets: inherit
lhci:
needs: prepare
if: needs.prepare.outputs.lhci_needed == 'true'
uses: ./.github/workflows/lhci.yml
secrets: inherit
# Same-repo only: forks cannot write to GHCR via `secrets.GITHUB_TOKEN`.
docker_build:
needs: [ prepare, lint, type_check, unit_test, integration_test, security_audit ]
if: >-
always() &&
needs.prepare.outputs.docker_build_needed == 'true' &&
!contains(needs.*.result, 'failure') &&
!contains(needs.*.result, 'cancelled')
# Job-level permissions override the workflow-level ceiling so the called
# reusable can declare `packages: write` without it being capped to `none`.
permissions:
contents: read
packages: write
uses: ./.github/workflows/docker_build.yml
secrets: inherit
# Same-repo only: forks cannot pull from GHCR via `secrets.GITHUB_TOKEN`.
e2e_test:
needs: [ prepare, docker_build ]
if: >-
always() &&
needs.prepare.outputs.e2e_test_needed == 'true' &&
needs.docker_build.result == 'success'
permissions:
contents: read
packages: read
uses: ./.github/workflows/e2e_test.yml
secrets: inherit
required:
name: Required
needs: [ prepare, lint, type_check, unit_test, integration_test, security_audit, lhci, docker_build, e2e_test ]
if: always()
runs-on: ubuntu-24.04-arm
timeout-minutes: 5
steps:
- name: Fail if conditional jobs failed
if: |
needs.prepare.result != 'success' ||
(needs.prepare.outputs.lint_needed == 'true' && needs.lint.result != 'success') ||
(needs.prepare.outputs.type_check_needed == 'true' && needs.type_check.result != 'success') ||
(needs.prepare.outputs.unit_test_needed == 'true' && needs.unit_test.result != 'success') ||
(needs.prepare.outputs.integration_test_needed == 'true' && needs.integration_test.result != 'success') ||
(needs.prepare.outputs.security_audit_needed == 'true' && needs.security_audit.result != 'success') ||
(needs.prepare.outputs.lhci_needed == 'true' && needs.lhci.result != 'success') ||
(needs.prepare.outputs.docker_build_needed == 'true' && needs.docker_build.result != 'success') ||
(needs.prepare.outputs.e2e_test_needed == 'true' && needs.e2e_test.result != 'success')
run: exit 1