Skip to content

feat: expose workflows and mesh from the taskito facade (#632) #1596

feat: expose workflows and mesh from the taskito facade (#632)

feat: expose workflows and mesh from the taskito facade (#632) #1596

Workflow file for this run

name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
# Allow manual re-triggers from the GitHub UI or `gh workflow run` —
# useful when master squash-merges arrive back-to-back and concurrency
# cancellations leave the latest master HEAD without a CI run.
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# CI only reads the repo. Pin the token to least privilege so a compromised
# step can't escalate. pull-requests:read lets dorny/paths-filter enumerate a
# PR's changed files on pull_request events.
permissions:
contents: read
pull-requests: read
jobs:
changes:
name: Detect changed paths
runs-on: ubuntu-latest
outputs:
# Run policy folded in: true on push/dispatch (run everything) or when a
# suite's paths changed on a PR. The per-suite jobs gate on these.
rust: ${{ steps.decide.outputs.rust }}
python: ${{ steps.decide.outputs.python }}
node: ${{ steps.decide.outputs.node }}
java: ${{ steps.decide.outputs.java }}
server: ${{ steps.decide.outputs.server }}
chart: ${{ steps.decide.outputs.chart }}
steps:
- name: Check out repository
uses: actions/checkout@v7.0.1
- name: Filter paths
id: filter
uses: dorny/paths-filter@v4
with:
# Each suite reruns when its own sources, the shared Rust core, the
# composite actions it actually uses, or its workflow change. Only
# setup-rust is shared by every suite; the other actions map to a
# single suite, so they no longer rerun all four.
filters: |
shared: &shared
- 'crates/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/actions/setup-rust/**'
- '.github/workflows/ci.yml'
rust:
- *shared
- '.github/actions/rust-prelude/**'
- '.github/actions/setup-python/**'
- 'rust-toolchain.toml'
- '.github/workflows/ci-rust.yml'
python:
- *shared
- '.github/actions/setup-python/**'
- 'sdks/python/**'
- '.github/workflows/ci-python.yml'
node:
- *shared
- '.github/actions/setup-node/**'
- 'sdks/node/**'
- 'dashboard/**'
- '.github/workflows/ci-node.yml'
java:
- *shared
- '.github/actions/setup-java/**'
- 'sdks/java/**'
- '.github/workflows/ci-java.yml'
# Deliberately not `*shared`: the image build is two from-scratch
# Rust compiles, and an engine-crate change that breaks the server
# already turns the Rust suite red. What only this suite covers is
# the Dockerfile and the SPA it embeds.
server:
- 'crates/taskito-server/**'
- 'dashboard/**'
- 'docker/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/ci-server-image.yml'
# Template rendering only — seconds, and independent of the image.
chart:
- 'deploy/helm/**'
- '.github/workflows/ci-chart.yml'
- name: Decide which suites run
id: decide
# FORCE is true on push and workflow_dispatch — run every suite there.
# On PRs honor the path filter.
env:
FORCE: ${{ github.event_name != 'pull_request' }}
RUST: ${{ steps.filter.outputs.rust }}
PYTHON: ${{ steps.filter.outputs.python }}
NODE: ${{ steps.filter.outputs.node }}
JAVA: ${{ steps.filter.outputs.java }}
SERVER: ${{ steps.filter.outputs.server }}
CHART: ${{ steps.filter.outputs.chart }}
run: |
decide() {
if [ "$FORCE" = "true" ] || [ "$2" = "true" ]; then
echo "$1=true" >> "$GITHUB_OUTPUT"
else
echo "$1=false" >> "$GITHUB_OUTPUT"
fi
}
decide rust "$RUST"
decide python "$PYTHON"
decide node "$NODE"
decide java "$JAVA"
decide server "$SERVER"
decide chart "$CHART"
versions:
name: Version consistency
runs-on: ubuntu-latest
# Unfiltered: the version spans every suite, and the check costs seconds.
steps:
- name: Check out repository
uses: actions/checkout@v7.0.1
- name: Every manifest agrees on one version
run: node scripts/version.mjs --check
rust:
name: Rust
needs: changes
if: needs.changes.outputs.rust == 'true'
uses: ./.github/workflows/ci-rust.yml
python:
name: Python
needs: changes
if: needs.changes.outputs.python == 'true'
uses: ./.github/workflows/ci-python.yml
node:
name: Node
needs: changes
if: needs.changes.outputs.node == 'true'
uses: ./.github/workflows/ci-node.yml
java:
name: Java
needs: changes
if: needs.changes.outputs.java == 'true'
uses: ./.github/workflows/ci-java.yml
server-image:
name: Server image
needs: changes
if: needs.changes.outputs.server == 'true'
uses: ./.github/workflows/ci-server-image.yml
chart:
name: Chart
needs: changes
if: needs.changes.outputs.chart == 'true'
uses: ./.github/workflows/ci-chart.yml
ci-status:
name: CI status
if: always()
needs: [changes, versions, rust, python, node, java, server-image, chart]
runs-on: ubuntu-latest
steps:
- name: Check that no required job failed
run: |
results='${{ toJson(needs) }}'
echo "$results"
fail=$(echo "$results" | python3 -c "
import json, sys
data = json.load(sys.stdin)
bad = [k for k, v in data.items() if v['result'] not in ('success', 'skipped')]
print(','.join(bad))
")
if [ -n "$fail" ]; then
echo "::error::Failing or cancelled jobs: $fail"
exit 1
fi