@@ -25,6 +25,7 @@ import {
2525 readDesignerTables ,
2626} from '../check-i18n-en-drift.mjs' ;
2727import { DESIGNER_TABLE } from '../check-i18n-designer-table-parity.mjs' ;
28+ import { globMatches , jobBlock , repoPath , rootCi , triggerBlock , uiFilterGlobs , uiRun , UI_JOBS , withoutComments } from './helpers/root-ci' ;
2829
2930/**
3031 * objectui#3650 — the behaviour test for `scripts/check-i18n-en-drift.mjs`.
@@ -964,55 +965,54 @@ describe('resolving the commit to compare against', () => {
964965
965966describe ( 'the gate is wired to run' , ( ) => {
966967 const pkg = JSON . parse ( fs . readFileSync ( path . join ( repoRoot , 'package.json' ) , 'utf8' ) ) ;
967- const ci = fs . readFileSync ( path . join ( repoRoot , '.github/workflows/ci.yml' ) , 'utf8' ) ;
968+ // The workflow GitHub runs: objectstack's root ci.yml, whose `type-check-ui`
969+ // job is objectui's `Type Check` (objectstack#25697). objectui's own ci.yml
970+ // under `ui/.github/` runs nowhere (objectstack#25712).
971+ const ci = rootCi ( ) ;
972+ const job = jobBlock ( ci , UI_JOBS . typeCheck ) ;
968973
969974 it ( 'package.json exposes it as a named script' , ( ) => {
970975 expect ( pkg . scripts [ 'check:i18n-drift' ] ) . toBe ( 'node scripts/check-i18n-en-drift.mjs' ) ;
971976 } ) ;
972977
973978 it ( 'ci.yml runs it after the install it needs (it imports typescript)' , ( ) => {
974- const install = ci . indexOf ( 'pnpm install --frozen-lockfile' ) ;
975- const step = ci . indexOf ( 'run: pnpm check:i18n-drift' ) ;
976- expect ( step , 'ci.yml does not run `pnpm check:i18n-drift`' ) . toBeGreaterThan ( - 1 ) ;
979+ const install = job . indexOf ( 'pnpm install --frozen-lockfile' ) ;
980+ const step = job . indexOf ( `run: ${ uiRun ( 'check:i18n-drift' ) } ` ) ;
981+ expect ( step , '`type-check-ui` does not run `pnpm --dir ui run check:i18n-drift`' ) . toBeGreaterThan ( - 1 ) ;
982+ expect ( install , '`type-check-ui` no longer installs dependencies' ) . toBeGreaterThan ( - 1 ) ;
977983 expect ( step , 'the check runs before dependencies are installed' ) . toBeGreaterThan ( install ) ;
978984 } ) ;
979985
980986 it ( 'gives that job a full-history checkout, or the merge base does not exist' , ( ) => {
981987 // actions/checkout defaults to depth 1. Without this the gate cannot resolve
982988 // a base — and by design that is a red build, not a silent pass, so losing
983989 // this line breaks CI loudly. The pin is here so the reason survives.
984- const job = ci . slice ( ci . indexOf ( ' type-check:' ) , ci . indexOf ( 'run: pnpm check:i18n-drift' ) ) ;
985- expect ( job ) . toContain ( 'fetch-depth: 0' ) ;
990+ const step = job . indexOf ( `run: ${ uiRun ( 'check:i18n-drift' ) } ` ) ;
991+ expect ( step , '`type-check-ui` does not run `pnpm --dir ui run check:i18n-drift`' ) . toBeGreaterThan ( - 1 ) ;
992+ expect ( job . slice ( 0 , step ) ) . toContain ( 'fetch-depth: 0' ) ;
986993 } ) ;
987994
988995 it ( 'is not hidden from the locale packs by ci.yml path filters' , ( ) => {
989- // ci.yml `paths-ignore`s markdown, content/, docs/, apps/site/ and
990- // .changeset/ on its `push` trigger — since objectui#3523 step 2 the only
991- // trigger that still carries the filter (ci.yml:6; lint.yml:32 is the twin),
992- // and the only thing the assertion below can see, since it slices the `on:`
993- // block. None of them can match `packages/i18n/src/locales/*.ts` or the
994- // ledger, so a push that edits an en string always starts this workflow.
996+ // The root ci.yml carries no `paths-ignore` on any trigger: it starts on
997+ // every pull_request, every queue build, every push to main and the hourly
998+ // schedule. What decides whether `type-check-ui` then runs is the `filter`
999+ // job's `ui:` paths filter, which the job's `if:` reads, so the ten locale
1000+ // packs, the ledger and the designer table must each match one of its
1001+ // globs. (Until objectstack#25712 this pinned objectui's own `push`
1002+ // `paths-ignore` list and its in-job `Decide whether this change needs a
1003+ // full run` step, in a ci.yml nothing runs; its near-verbatim twin is in
1004+ // `check-action-forward-parity.test.ts`.)
9951005 //
996- // For a PULL REQUEST the conclusion holds for a second and stronger reason.
997- // This lead-in used to state it in a bare present tense that read as if the
998- // filter still applied there; objectui#4384 qualified it, together with its
999- // near-verbatim twin in `check-action-forward-parity.test.ts`, closing the
1000- // #3857 / #4369 / #4381 family (PRs #4371 / #4380 / #4382). No
1001- // `paths-ignore` survives on `pull_request` at all, so such a PR starts this
1002- // workflow a fortiori — measured there: PR #3856, one markdown file, 16
1003- // checks. What decides a pull request now is the in-job `Decide whether this
1004- // change needs a full run` step, whose exclusion list is that `push` filter
1005- // unchanged, held identical to it by
1006- // `scripts/__tests__/merge-queue-reporting.test.ts` — so the patterns pinned
1007- // below are also what keeps the expensive steps running on a locale-pack PR.
1008- //
1009- // A new entry that DID cover them would make the gate unreachable for
1010- // exactly the PRs it judges, on both lanes at once — the objectui#3547 /
1011- // control-bytes.yml lesson, one workflow over.
1012- const ignored = ci . slice ( 0 , ci . indexOf ( 'jobs:' ) ) . match ( / ^ \s + - ' .* ' $ / gm) ?? [ ] ;
1013- for ( const pattern of ignored ) {
1014- expect ( pattern ) . not . toMatch ( / p a c k a g e s | s c r i p t s | l o c a l e s / ) ;
1006+ // A glob set that missed them would make the gate unreachable for exactly
1007+ // the PRs it judges — the objectui#3547 / control-bytes.yml lesson, one
1008+ // workflow over.
1009+ expect ( withoutComments ( triggerBlock ( ci ) ) , 'a trigger grew a path filter' ) . not . toMatch ( / ^ \s + p a t h s ( - i g n o r e ) ? : / m) ;
1010+ expect ( job , '`type-check-ui` no longer reads the `ui` filter output' ) . toContain (
1011+ "needs.filter.outputs.ui != 'false'" ,
1012+ ) ;
1013+ const globs = uiFilterGlobs ( ci ) ;
1014+ for ( const file of [ ...LOCALES . map ( packPath ) , LEDGER_PATH , DESIGNER_TABLE ] . map ( repoPath ) ) {
1015+ expect ( globs . some ( ( glob ) => globMatches ( glob , file ) ) , `no \`ui:\` filter glob covers ${ file } ` ) . toBe ( true ) ;
10151016 }
1016- expect ( ignored . length ) . toBeGreaterThan ( 0 ) ;
10171017 } ) ;
10181018} ) ;
0 commit comments