From f4cb4162b5f0a010d87343e87b98a03760ee870c Mon Sep 17 00:00:00 2001 From: dqn Date: Sat, 27 Jun 2026 17:30:29 +0900 Subject: [PATCH 1/4] ci: run independent checks in parallel --- .github/workflows/ci.yml | 70 ++++++++++++----------- .github/workflows/github-actions-lint.yml | 4 +- .github/workflows/template-tests.yml | 29 +++++----- 3 files changed, 54 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e49e13be1..f6642429c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,46 +36,48 @@ jobs: - name: Build packages run: pnpm -r --filter '!@tailor-platform/sdk' run build - - name: Run lint - run: pnpm -r run lint - - - name: Run Vitest lint - run: pnpm run lint:vitest - - # Ensure no executable files are present - # refs: https://github.com/changesets/action/issues/523 - # Skip symlinks: `-x` follows symlinks to directories and reports them as executable. - - name: Check for executable files - run: | - executable_files=$(git ls-files | while read -r file; do [ ! -L "$file" ] && [ -x "$file" ] && echo "$file"; done || true) - if [ -n "$executable_files" ]; then - echo "Error: Found executable files (changesets/action does not support executable files):" - echo "$executable_files" - exit 1 - fi - - - name: Check format - run: pnpm format:check + - parallel: + - name: Run lint + run: pnpm -r run lint + + - name: Run Vitest lint + run: pnpm run lint:vitest + + # Ensure no executable files are present + # refs: https://github.com/changesets/action/issues/523 + # Skip symlinks: `-x` follows symlinks to directories and reports them as executable. + - name: Check for executable files + run: | + executable_files=$(git ls-files | while read -r file; do [ ! -L "$file" ] && [ -x "$file" ] && echo "$file"; done || true) + if [ -n "$executable_files" ]; then + echo "Error: Found executable files (changesets/action does not support executable files):" + echo "$executable_files" + exit 1 + fi + + - name: Check format + run: pnpm format:check - name: Generate code run: pnpm -r run generate - - name: Check type by tsgo - run: pnpm -r run typecheck:go + - parallel: + - name: Check type by tsgo + run: pnpm -r run typecheck:go - - name: Check type - run: pnpm -r run typecheck + - name: Check unused code (knip) + run: pnpm -r run knip - - name: Check unused code (knip) - run: pnpm -r run knip + - name: Check package exports (publint) + run: pnpm -r run publint - - name: Check package exports (publint) - run: pnpm -r run publint + # zod must not leak into user-facing entry points (operates on dist/, + # already built by install-deps). + - name: Check zod isolation + run: pnpm -r run check:zod-isolation - # zod must not leak into user-facing entry points (operates on dist/, - # already built by install-deps). - - name: Check zod isolation - run: pnpm -r run check:zod-isolation + - name: Check import cycles + run: pnpm -r run check:import-cycles - - name: Check import cycles - run: pnpm -r run check:import-cycles + - name: Check type + run: pnpm -r run typecheck diff --git a/.github/workflows/github-actions-lint.yml b/.github/workflows/github-actions-lint.yml index 284404e454..8b38a48f5a 100644 --- a/.github/workflows/github-actions-lint.yml +++ b/.github/workflows/github-actions-lint.yml @@ -40,7 +40,9 @@ jobs: uses: ./.github/actions/install-aqua - name: Run actionlint - run: actionlint -color + run: >- + actionlint -color + -ignore 'step must run script with "run" section or run action with "uses" section' - name: Run ghalint workflows run: ghalint run diff --git a/.github/workflows/template-tests.yml b/.github/workflows/template-tests.yml index f2af6d5f00..a75741ecdc 100644 --- a/.github/workflows/template-tests.yml +++ b/.github/workflows/template-tests.yml @@ -39,18 +39,19 @@ jobs: - name: Install deps uses: ./.github/actions/install-deps - - name: Typecheck templates - run: >- - pnpm -r - --filter "./packages/create-sdk/templates/*" - run typecheck + - parallel: + - name: Typecheck templates + run: >- + pnpm -r + --filter "./packages/create-sdk/templates/*" + run typecheck - - name: Run template unit tests - run: >- - pnpm -r - --filter "./packages/create-sdk/templates/tailordb" - --filter "./packages/create-sdk/templates/resolver" - --filter "./packages/create-sdk/templates/workflow" - --filter "./packages/create-sdk/templates/executor" - --filter "./packages/create-sdk/templates/generators" - run test:unit + - name: Run template unit tests + run: >- + pnpm -r + --filter "./packages/create-sdk/templates/tailordb" + --filter "./packages/create-sdk/templates/resolver" + --filter "./packages/create-sdk/templates/workflow" + --filter "./packages/create-sdk/templates/executor" + --filter "./packages/create-sdk/templates/generators" + run test:unit From 76730ec621cc2b0ccb439d02f34832626e9370e1 Mon Sep 17 00:00:00 2001 From: dqn Date: Sat, 27 Jun 2026 17:36:14 +0900 Subject: [PATCH 2/4] ci: document actionlint parallel-step workaround --- .github/workflows/github-actions-lint.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-actions-lint.yml b/.github/workflows/github-actions-lint.yml index 8b38a48f5a..0106813db6 100644 --- a/.github/workflows/github-actions-lint.yml +++ b/.github/workflows/github-actions-lint.yml @@ -40,9 +40,10 @@ jobs: uses: ./.github/actions/install-aqua - name: Run actionlint + # actionlint v1.7.12 does not recognize GitHub's step-level parallel syntax yet. run: >- actionlint -color - -ignore 'step must run script with "run" section or run action with "uses" section' + -ignore '^step must run script with "run" section or run action with "uses" section$' - name: Run ghalint workflows run: ghalint run From d4851de8ac0135309508c09061825cadfd2e43f3 Mon Sep 17 00:00:00 2001 From: dqn Date: Sat, 27 Jun 2026 17:43:49 +0900 Subject: [PATCH 3/4] ci: scope actionlint parallel-step workaround --- .github/scripts/actionlint-allow-parallel.mjs | 63 +++++++++++++++++++ .github/workflows/github-actions-lint.yml | 6 +- 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 .github/scripts/actionlint-allow-parallel.mjs diff --git a/.github/scripts/actionlint-allow-parallel.mjs b/.github/scripts/actionlint-allow-parallel.mjs new file mode 100644 index 0000000000..38ff732e8e --- /dev/null +++ b/.github/scripts/actionlint-allow-parallel.mjs @@ -0,0 +1,63 @@ +import { spawnSync } from "node:child_process"; +import { readFileSync } from "node:fs"; + +const result = spawnSync("actionlint", ["-format", "{{json .}}"], { + encoding: "utf8", +}); + +if (result.status === 0) { + process.exit(0); +} + +if (result.error) { + console.error(result.error.message); + process.exit(1); +} + +let diagnostics; +try { + diagnostics = JSON.parse(result.stdout); +} catch { + process.stdout.write(result.stdout); + process.stderr.write(result.stderr); + process.exit(result.status ?? 1); +} + +const isParallelSyntaxDiagnostic = (diagnostic) => { + if ( + diagnostic.kind !== "syntax-check" || + diagnostic.message !== + 'step must run script with "run" section or run action with "uses" section' || + !diagnostic.filepath || + !Number.isInteger(diagnostic.line) + ) { + return false; + } + + const line = readFileSync(diagnostic.filepath, "utf8").split(/\r?\n/u)[diagnostic.line - 1]; + return line?.trim() === "- parallel:"; +}; + +const remaining = diagnostics.filter((diagnostic) => !isParallelSyntaxDiagnostic(diagnostic)); +const ignoredCount = diagnostics.length - remaining.length; + +if (ignoredCount > 0) { + console.error( + `actionlint: ignored ${ignoredCount} diagnostic(s) for GitHub's step-level parallel syntax`, + ); +} + +if (remaining.length === 0) { + process.exit(0); +} + +for (const diagnostic of remaining) { + console.error( + `${diagnostic.filepath}:${diagnostic.line}:${diagnostic.column}: ${diagnostic.message} [${diagnostic.kind}]`, + ); + if (diagnostic.snippet) { + console.error(diagnostic.snippet); + } +} + +process.exit(1); diff --git a/.github/workflows/github-actions-lint.yml b/.github/workflows/github-actions-lint.yml index 0106813db6..56d14c7288 100644 --- a/.github/workflows/github-actions-lint.yml +++ b/.github/workflows/github-actions-lint.yml @@ -12,6 +12,7 @@ on: - .github/workflows/*.yaml - .github/workflows/*.yml - .github/actions/** + - .github/scripts/** - aqua.yaml - aqua-checksums.json - .ghalint.yaml @@ -40,10 +41,7 @@ jobs: uses: ./.github/actions/install-aqua - name: Run actionlint - # actionlint v1.7.12 does not recognize GitHub's step-level parallel syntax yet. - run: >- - actionlint -color - -ignore '^step must run script with "run" section or run action with "uses" section$' + run: node .github/scripts/actionlint-allow-parallel.mjs - name: Run ghalint workflows run: ghalint run From 699555c3dcfab8193f81ef9648ea87d424415a46 Mon Sep 17 00:00:00 2001 From: dqn Date: Sat, 4 Jul 2026 17:13:52 +0900 Subject: [PATCH 4/4] ci: remove actionlint parallel workaround --- .github/scripts/actionlint-allow-parallel.mjs | 63 ------------------- .github/workflows/github-actions-lint.yml | 3 +- 2 files changed, 1 insertion(+), 65 deletions(-) delete mode 100644 .github/scripts/actionlint-allow-parallel.mjs diff --git a/.github/scripts/actionlint-allow-parallel.mjs b/.github/scripts/actionlint-allow-parallel.mjs deleted file mode 100644 index 38ff732e8e..0000000000 --- a/.github/scripts/actionlint-allow-parallel.mjs +++ /dev/null @@ -1,63 +0,0 @@ -import { spawnSync } from "node:child_process"; -import { readFileSync } from "node:fs"; - -const result = spawnSync("actionlint", ["-format", "{{json .}}"], { - encoding: "utf8", -}); - -if (result.status === 0) { - process.exit(0); -} - -if (result.error) { - console.error(result.error.message); - process.exit(1); -} - -let diagnostics; -try { - diagnostics = JSON.parse(result.stdout); -} catch { - process.stdout.write(result.stdout); - process.stderr.write(result.stderr); - process.exit(result.status ?? 1); -} - -const isParallelSyntaxDiagnostic = (diagnostic) => { - if ( - diagnostic.kind !== "syntax-check" || - diagnostic.message !== - 'step must run script with "run" section or run action with "uses" section' || - !diagnostic.filepath || - !Number.isInteger(diagnostic.line) - ) { - return false; - } - - const line = readFileSync(diagnostic.filepath, "utf8").split(/\r?\n/u)[diagnostic.line - 1]; - return line?.trim() === "- parallel:"; -}; - -const remaining = diagnostics.filter((diagnostic) => !isParallelSyntaxDiagnostic(diagnostic)); -const ignoredCount = diagnostics.length - remaining.length; - -if (ignoredCount > 0) { - console.error( - `actionlint: ignored ${ignoredCount} diagnostic(s) for GitHub's step-level parallel syntax`, - ); -} - -if (remaining.length === 0) { - process.exit(0); -} - -for (const diagnostic of remaining) { - console.error( - `${diagnostic.filepath}:${diagnostic.line}:${diagnostic.column}: ${diagnostic.message} [${diagnostic.kind}]`, - ); - if (diagnostic.snippet) { - console.error(diagnostic.snippet); - } -} - -process.exit(1); diff --git a/.github/workflows/github-actions-lint.yml b/.github/workflows/github-actions-lint.yml index 56d14c7288..284404e454 100644 --- a/.github/workflows/github-actions-lint.yml +++ b/.github/workflows/github-actions-lint.yml @@ -12,7 +12,6 @@ on: - .github/workflows/*.yaml - .github/workflows/*.yml - .github/actions/** - - .github/scripts/** - aqua.yaml - aqua-checksums.json - .ghalint.yaml @@ -41,7 +40,7 @@ jobs: uses: ./.github/actions/install-aqua - name: Run actionlint - run: node .github/scripts/actionlint-allow-parallel.mjs + run: actionlint -color - name: Run ghalint workflows run: ghalint run