From 0cdafa18ce743e820455fcc09c668ef372e0ca9d Mon Sep 17 00:00:00 2001 From: imbajin Date: Thu, 17 Sep 2026 22:06:53 +0800 Subject: [PATCH 1/4] chore(ci): skip unrelated PR build jobs - share conservative PR path selection across build workflows - retain required check names and full non-PR coverage - add rename and API fallback regression checks - document filtering and correct branch globs --- .github/scripts/test-ci-scope.cjs | 60 +++++++++++++++ .github/workflows/check-dependencies.yml | 12 ++- .github/workflows/ci-scope.yml | 98 ++++++++++++++++++++++++ .github/workflows/cluster-test-ci.yml | 10 +++ .github/workflows/commons-ci.yml | 14 +++- .github/workflows/docker-build-ci.yml | 26 +++---- .github/workflows/pd-store-ci.yml | 19 ++++- .github/workflows/server-ci.yml | 16 ++++ docs/BUILDING.md | 14 ++++ 9 files changed, 249 insertions(+), 20 deletions(-) create mode 100644 .github/scripts/test-ci-scope.cjs create mode 100644 .github/workflows/ci-scope.yml diff --git a/.github/scripts/test-ci-scope.cjs b/.github/scripts/test-ci-scope.cjs new file mode 100644 index 0000000000..f5695001d5 --- /dev/null +++ b/.github/scripts/test-ci-scope.cjs @@ -0,0 +1,60 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +const assert = require('node:assert/strict'); +const runScript = new (Object.getPrototypeOf(async function(){}).constructor)( + 'process', 'context', 'github', 'core', + require('node:fs').readFileSync( + require('node:path').join(__dirname, '../workflows/ci-scope.yml'), 'utf8') + .split(' script: |\n')[1].split('\n') + .map(line => line.slice(12)).join('\n')); +async function check(scope, names, expected, opts = {}) { + let output; + const files = names.map(x => typeof x === 'string' ? {filename:x} : x); + const github = { + paginate: async () => { if(opts.error) throw Error('offline'); return files; }, + rest:{pulls:{listFiles:()=>{},get: async()=>({data:{ + changed_files: opts.count ?? files.length, head:{sha:opts.head ?? 'abc'} + }})}} + }; + await runScript({env:{CI_SCOPE:scope}}, + {eventName:opts.event ?? 'pull_request',repo:{owner:'x',repo:'y'}, + payload:{pull_request:{number:1,head:{sha:'abc'}}}}, + github,{warning:()=>{},setOutput:(k,v)=>output=v}); + assert.equal(output,String(expected),scope+': '+JSON.stringify(names)); +} +(async()=>{ +for(const scope of ['commons','server','distributed','cluster','docker','dependencies']) { + await check(scope,['README.md','hugegraph-server/AGENTS.md','.serena/project.yml'],false); + await check(scope,['pom.xml'],true); + await check(scope,['.github/workflows/ci-scope.yml'],true); + await check(scope,['README.md'],true,{error:true}); + await check(scope,['README.md'],true,{count:3001}); + await check(scope,['README.md'],true,{head:'moved'}); + await check(scope,['README.md'],true,{event:'push'}); + await check(scope,['README.md'],true,{event:'workflow_dispatch'}); +} +await check('commons',['hugegraph-store/hg-store-core/src/main/java/A.java'],false); +await check('server',['hugegraph-commons/hugegraph-common/src/main/java/A.java'],true); +await check('distributed',['hugegraph-server/hugegraph-hstore/src/main/java/A.java'],true); +await check('docker',['hugegraph-server/hugegraph-dist/src/assembly/static/conf/x.txt'],true); +await check('server',['hugegraph-server/hugegraph-test/src/main/resources/case.md'],true); +await check('dependencies',['install-dist/scripts/dependency/known-dependencies.txt'],true); +await check('server',[{filename:'docs/old.md',previous_filename:'hugegraph-server/A.java'}],true); +await check('server',['new-build-tool.sh'],true); +console.log('56 path and fallback scenarios passed'); +})().catch(e=>{console.error(e);process.exit(1)}); diff --git a/.github/workflows/check-dependencies.yml b/.github/workflows/check-dependencies.yml index 447162d67f..cdd21e3e2f 100644 --- a/.github/workflows/check-dependencies.yml +++ b/.github/workflows/check-dependencies.yml @@ -4,14 +4,24 @@ name: "3rd-party" on: push: branches: - - /^release-.*$/ + - 'release-*' pull_request: permissions: contents: read jobs: + changes: + uses: ./.github/workflows/ci-scope.yml + permissions: + contents: read + pull-requests: read + with: + scope: dependencies + dependency-check: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/ci-scope.yml b/.github/workflows/ci-scope.yml new file mode 100644 index 0000000000..b8eb843817 --- /dev/null +++ b/.github/workflows/ci-scope.yml @@ -0,0 +1,98 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: CI scope + +on: + workflow_call: + inputs: + scope: + required: true + type: string + outputs: + run: + value: ${{ jobs.changes.outputs.run }} + +permissions: + contents: read + pull-requests: read + +jobs: + changes: + runs-on: ubuntu-latest + outputs: + run: ${{ steps.paths.outputs.run }} + steps: + # No checkout or execution of PR code. Inspect the complete PR, including renamed paths. + - uses: actions/github-script@v7 + id: paths + env: + CI_SCOPE: ${{ inputs.scope }} + with: + script: | + const scope = process.env.CI_SCOPE; + const modules = { + commons: ['hugegraph-commons/'], + server: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', + 'hugegraph-store/', 'hugegraph-server/'], + distributed: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', + 'hugegraph-store/', 'hugegraph-server/'], + cluster: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', + 'hugegraph-store/', 'hugegraph-server/', 'hugegraph-cluster-test/'], + docker: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', + 'hugegraph-store/', 'hugegraph-server/', 'hugegraph-cluster-test/', + 'docker/', 'install-dist/'], + dependencies: [] + }; + const relevant = path => { + // Only known documentation locations; src resources and license inventories count. + if (path.startsWith('.serena/') || path.startsWith('docs/') || + path === '.github/PULL_REQUEST_TEMPLATE.md' || + (/\.(md|rst)$/i.test(path) && !path.includes('/src/'))) return false; + // Shared build inputs and CI changes conservatively exercise every scope. + if (path.endsWith('pom.xml') || path.startsWith('.github/') || + path.startsWith('.mvn/') || path.startsWith('style/') || + ['.editorconfig', '.dockerignore', 'mvnw', 'mvnw.cmd'].includes(path)) return true; + if (scope === 'dependencies') { + return path.startsWith('install-dist/') || /\.(jar|gradle|kts)$/.test(path); + } + const knownModules = modules.docker.filter(prefix => prefix.startsWith('hugegraph-')); + return modules[scope].some(prefix => path.startsWith(prefix)) || + !knownModules.some(prefix => path.startsWith(prefix)); + }; + let run = true; + try { + if (!(scope in modules)) throw new Error('Unknown CI scope: ' + scope); + if (context.eventName === 'pull_request') { + const pr = context.payload.pull_request; + const files = await github.paginate(github.rest.pulls.listFiles, { + ...context.repo, pull_number: pr.number, per_page: 100 + }); + // The API caps at 3000 files. An incomplete or stale result must not skip tests. + const { data: current } = await github.rest.pulls.get({ + ...context.repo, pull_number: pr.number + }); + if (files.length === current.changed_files && files.length < 3000 && + current.head.sha === pr.head.sha) { + run = files.some(file => relevant(file.filename) || + (file.previous_filename && relevant(file.previous_filename))); + } + } + } catch (error) { + core.warning('Cannot safely filter changes; running CI: ' + error.message); + } + core.setOutput('run', String(run)); diff --git a/.github/workflows/cluster-test-ci.yml b/.github/workflows/cluster-test-ci.yml index 3ef269e878..322b9c6200 100644 --- a/.github/workflows/cluster-test-ci.yml +++ b/.github/workflows/cluster-test-ci.yml @@ -9,7 +9,17 @@ on: pull_request: jobs: + changes: + uses: ./.github/workflows/ci-scope.yml + permissions: + contents: read + pull-requests: read + with: + scope: cluster + cluster-test: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/commons-ci.yml b/.github/workflows/commons-ci.yml index a03aaf09ff..0e532f5dc6 100644 --- a/.github/workflows/commons-ci.yml +++ b/.github/workflows/commons-ci.yml @@ -5,12 +5,22 @@ on: push: branches: - master - - /^release-.*$/ - - /^test-.*$/ + - 'release-*' + - 'test-*' pull_request: jobs: + changes: + uses: ./.github/workflows/ci-scope.yml + permissions: + contents: read + pull-requests: read + with: + scope: commons + build-commons: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index 706ae52d56..6d36ba356f 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -23,23 +23,19 @@ on: - master - 'release-*' pull_request: - paths: - - '.github/workflows/docker-build-ci.yml' - - 'docker/bake.hcl' - - '.dockerignore' - - '.mvn/**' - - 'pom.xml' - - 'hugegraph-commons/**' - - 'hugegraph-cluster-test/**' - - 'hugegraph-pd/**' - - 'hugegraph-store/**' - - 'hugegraph-struct/**' - - 'hugegraph-server/**' - - 'docker/hbase/**' - - 'install-dist/**' jobs: + changes: + uses: ./.github/workflows/ci-scope.yml + permissions: + contents: read + pull-requests: read + with: + scope: docker + docker-bake-check: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest steps: - name: Checkout @@ -103,6 +99,8 @@ jobs: ' /tmp/hugegraph-bake.json docker-build: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index 48b5ae8c0b..fb9c91131f 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -10,7 +10,17 @@ on: # TODO: consider merge to one ci.yml file jobs: + changes: + uses: ./.github/workflows/ci-scope.yml + permissions: + contents: read + pull-requests: read + with: + scope: distributed + struct: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' @@ -64,7 +74,8 @@ jobs: mvn -U -ntp -pl hugegraph-struct test pd: - needs: struct + needs: [changes, struct] + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: # TODO: avoid duplicated env setup in pd & store @@ -203,7 +214,8 @@ jobs: fail_ci_if_error: false store: - needs: struct + needs: [changes, struct] + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. @@ -347,7 +359,8 @@ jobs: fail_ci_if_error: false hstore: - needs: struct + needs: [changes, struct] + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index b5f5efc270..58a6a2c7c2 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -9,7 +9,17 @@ on: pull_request: jobs: + changes: + uses: ./.github/workflows/ci-scope.yml + permissions: + contents: read + pull-requests: read + with: + scope: server + wait-storage-shell-test: + needs: changes + if: needs.changes.outputs.run == 'true' permissions: contents: read runs-on: ubuntu-24.04 @@ -23,6 +33,8 @@ jobs: run: hugegraph-server/hugegraph-dist/src/assembly/travis/test-wait-storage.sh build-server: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ubuntu-24.04 env: USE_STAGE: 'false' # Whether to include the stage repository. @@ -178,6 +190,8 @@ jobs: fail_ci_if_error: false build-server-macos-rocksdb: + needs: changes + if: needs.changes.outputs.run == 'true' runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -258,6 +272,8 @@ jobs: fi build-server-riscv64: + needs: changes + if: needs.changes.outputs.run == 'true' uses: ./.github/workflows/riscv64-ci.yml permissions: contents: read diff --git a/docs/BUILDING.md b/docs/BUILDING.md index d4c807c748..a0af8d7476 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -39,3 +39,17 @@ To find the Java binary in your environment, run the appropriate command for you * Linux/macOS: `which java` * Windows: `for %i in (java.exe) do @echo. %~$PATH:i` + +## CI change selection + +Pull requests use `.github/workflows/ci-scope.yml` to skip unrelated build jobs. +Known documentation changes skip ordinary Maven and Docker builds; source resources +(including text fixtures), shared POMs and CI configuration still trigger relevant checks. +Shared component changes include downstream modules. Unknown paths are handled conservatively. +Dependency compilation runs for POMs, dependency inventories, packaged JARs and build configuration. + +Workflow triggers and required job names remain present, avoiding pending required checks. +CodeQL, license checks and dependency review remain enabled. Push, scheduled and manual runs +retain their existing coverage. Failed or incomplete file discovery falls back to running CI. + +Validate path selection locally with `node .github/scripts/test-ci-scope.cjs`. From a2eba4dfc32020efd85065d508d6ba7810ec4c80 Mon Sep 17 00:00:00 2001 From: imbajin Date: Thu, 17 Sep 2026 22:12:44 +0800 Subject: [PATCH 2/4] chore(ci): simplify filtering with native paths - remove custom scope workflow and JavaScript tests - use native PR path filters for non-required workflows - retain required checks and original job dependencies - document the narrower filtering scope --- .github/scripts/test-ci-scope.cjs | 60 --------------- .github/workflows/check-dependencies.yml | 21 ++--- .github/workflows/ci-scope.yml | 98 ------------------------ .github/workflows/cluster-test-ci.yml | 28 ++++--- .github/workflows/commons-ci.yml | 10 --- .github/workflows/docker-build-ci.yml | 32 +++++--- .github/workflows/pd-store-ci.yml | 37 +++++---- .github/workflows/server-ci.yml | 16 ---- docs/BUILDING.md | 19 ++--- 9 files changed, 78 insertions(+), 243 deletions(-) delete mode 100644 .github/scripts/test-ci-scope.cjs delete mode 100644 .github/workflows/ci-scope.yml diff --git a/.github/scripts/test-ci-scope.cjs b/.github/scripts/test-ci-scope.cjs deleted file mode 100644 index f5695001d5..0000000000 --- a/.github/scripts/test-ci-scope.cjs +++ /dev/null @@ -1,60 +0,0 @@ -// -// Licensed to the Apache Software Foundation (ASF) under one or more -// contributor license agreements. See the NOTICE file distributed with -// this work for additional information regarding copyright ownership. -// The ASF licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -const assert = require('node:assert/strict'); -const runScript = new (Object.getPrototypeOf(async function(){}).constructor)( - 'process', 'context', 'github', 'core', - require('node:fs').readFileSync( - require('node:path').join(__dirname, '../workflows/ci-scope.yml'), 'utf8') - .split(' script: |\n')[1].split('\n') - .map(line => line.slice(12)).join('\n')); -async function check(scope, names, expected, opts = {}) { - let output; - const files = names.map(x => typeof x === 'string' ? {filename:x} : x); - const github = { - paginate: async () => { if(opts.error) throw Error('offline'); return files; }, - rest:{pulls:{listFiles:()=>{},get: async()=>({data:{ - changed_files: opts.count ?? files.length, head:{sha:opts.head ?? 'abc'} - }})}} - }; - await runScript({env:{CI_SCOPE:scope}}, - {eventName:opts.event ?? 'pull_request',repo:{owner:'x',repo:'y'}, - payload:{pull_request:{number:1,head:{sha:'abc'}}}}, - github,{warning:()=>{},setOutput:(k,v)=>output=v}); - assert.equal(output,String(expected),scope+': '+JSON.stringify(names)); -} -(async()=>{ -for(const scope of ['commons','server','distributed','cluster','docker','dependencies']) { - await check(scope,['README.md','hugegraph-server/AGENTS.md','.serena/project.yml'],false); - await check(scope,['pom.xml'],true); - await check(scope,['.github/workflows/ci-scope.yml'],true); - await check(scope,['README.md'],true,{error:true}); - await check(scope,['README.md'],true,{count:3001}); - await check(scope,['README.md'],true,{head:'moved'}); - await check(scope,['README.md'],true,{event:'push'}); - await check(scope,['README.md'],true,{event:'workflow_dispatch'}); -} -await check('commons',['hugegraph-store/hg-store-core/src/main/java/A.java'],false); -await check('server',['hugegraph-commons/hugegraph-common/src/main/java/A.java'],true); -await check('distributed',['hugegraph-server/hugegraph-hstore/src/main/java/A.java'],true); -await check('docker',['hugegraph-server/hugegraph-dist/src/assembly/static/conf/x.txt'],true); -await check('server',['hugegraph-server/hugegraph-test/src/main/resources/case.md'],true); -await check('dependencies',['install-dist/scripts/dependency/known-dependencies.txt'],true); -await check('server',[{filename:'docs/old.md',previous_filename:'hugegraph-server/A.java'}],true); -await check('server',['new-build-tool.sh'],true); -console.log('56 path and fallback scenarios passed'); -})().catch(e=>{console.error(e);process.exit(1)}); diff --git a/.github/workflows/check-dependencies.yml b/.github/workflows/check-dependencies.yml index cdd21e3e2f..23efa75ddb 100644 --- a/.github/workflows/check-dependencies.yml +++ b/.github/workflows/check-dependencies.yml @@ -6,22 +6,23 @@ on: branches: - 'release-*' pull_request: + # Keep source/resources and shared build inputs; skip named documentation files. + paths: + - '**/pom.xml' + - '.mvn/**' + - '.github/configs/**' + - 'install-dist/**' + - '**/*.jar' + - '.github/workflows/check-dependencies.yml' + - '!**/README*' + - '!**/AGENTS.md' + - '!**/CLAUDE.md' permissions: contents: read jobs: - changes: - uses: ./.github/workflows/ci-scope.yml - permissions: - contents: read - pull-requests: read - with: - scope: dependencies - dependency-check: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/ci-scope.yml b/.github/workflows/ci-scope.yml deleted file mode 100644 index b8eb843817..0000000000 --- a/.github/workflows/ci-scope.yml +++ /dev/null @@ -1,98 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -name: CI scope - -on: - workflow_call: - inputs: - scope: - required: true - type: string - outputs: - run: - value: ${{ jobs.changes.outputs.run }} - -permissions: - contents: read - pull-requests: read - -jobs: - changes: - runs-on: ubuntu-latest - outputs: - run: ${{ steps.paths.outputs.run }} - steps: - # No checkout or execution of PR code. Inspect the complete PR, including renamed paths. - - uses: actions/github-script@v7 - id: paths - env: - CI_SCOPE: ${{ inputs.scope }} - with: - script: | - const scope = process.env.CI_SCOPE; - const modules = { - commons: ['hugegraph-commons/'], - server: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', - 'hugegraph-store/', 'hugegraph-server/'], - distributed: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', - 'hugegraph-store/', 'hugegraph-server/'], - cluster: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', - 'hugegraph-store/', 'hugegraph-server/', 'hugegraph-cluster-test/'], - docker: ['hugegraph-commons/', 'hugegraph-struct/', 'hugegraph-pd/', - 'hugegraph-store/', 'hugegraph-server/', 'hugegraph-cluster-test/', - 'docker/', 'install-dist/'], - dependencies: [] - }; - const relevant = path => { - // Only known documentation locations; src resources and license inventories count. - if (path.startsWith('.serena/') || path.startsWith('docs/') || - path === '.github/PULL_REQUEST_TEMPLATE.md' || - (/\.(md|rst)$/i.test(path) && !path.includes('/src/'))) return false; - // Shared build inputs and CI changes conservatively exercise every scope. - if (path.endsWith('pom.xml') || path.startsWith('.github/') || - path.startsWith('.mvn/') || path.startsWith('style/') || - ['.editorconfig', '.dockerignore', 'mvnw', 'mvnw.cmd'].includes(path)) return true; - if (scope === 'dependencies') { - return path.startsWith('install-dist/') || /\.(jar|gradle|kts)$/.test(path); - } - const knownModules = modules.docker.filter(prefix => prefix.startsWith('hugegraph-')); - return modules[scope].some(prefix => path.startsWith(prefix)) || - !knownModules.some(prefix => path.startsWith(prefix)); - }; - let run = true; - try { - if (!(scope in modules)) throw new Error('Unknown CI scope: ' + scope); - if (context.eventName === 'pull_request') { - const pr = context.payload.pull_request; - const files = await github.paginate(github.rest.pulls.listFiles, { - ...context.repo, pull_number: pr.number, per_page: 100 - }); - // The API caps at 3000 files. An incomplete or stale result must not skip tests. - const { data: current } = await github.rest.pulls.get({ - ...context.repo, pull_number: pr.number - }); - if (files.length === current.changed_files && files.length < 3000 && - current.head.sha === pr.head.sha) { - run = files.some(file => relevant(file.filename) || - (file.previous_filename && relevant(file.previous_filename))); - } - } - } catch (error) { - core.warning('Cannot safely filter changes; running CI: ' + error.message); - } - core.setOutput('run', String(run)); diff --git a/.github/workflows/cluster-test-ci.yml b/.github/workflows/cluster-test-ci.yml index 322b9c6200..c2972cb9f9 100644 --- a/.github/workflows/cluster-test-ci.yml +++ b/.github/workflows/cluster-test-ci.yml @@ -7,19 +7,27 @@ on: - 'release-*' - 'test-*' pull_request: + # Keep source/resources and shared build inputs; skip named documentation files. + paths: + - 'pom.xml' + - '.mvn/**' + - 'style/**' + - '.editorconfig' + - '.github/configs/**' + - 'hugegraph-commons/**' + - 'hugegraph-struct/**' + - 'hugegraph-pd/**' + - 'hugegraph-store/**' + - 'hugegraph-server/**' + - 'hugegraph-cluster-test/**' + - 'install-dist/**' + - '.github/workflows/cluster-test-ci.yml' + - '!**/README*' + - '!**/AGENTS.md' + - '!**/CLAUDE.md' jobs: - changes: - uses: ./.github/workflows/ci-scope.yml - permissions: - contents: read - pull-requests: read - with: - scope: cluster - cluster-test: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/commons-ci.yml b/.github/workflows/commons-ci.yml index 0e532f5dc6..fd01df1825 100644 --- a/.github/workflows/commons-ci.yml +++ b/.github/workflows/commons-ci.yml @@ -10,17 +10,7 @@ on: pull_request: jobs: - changes: - uses: ./.github/workflows/ci-scope.yml - permissions: - contents: read - pull-requests: read - with: - scope: commons - build-commons: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/docker-build-ci.yml b/.github/workflows/docker-build-ci.yml index 6d36ba356f..97e2d37a41 100644 --- a/.github/workflows/docker-build-ci.yml +++ b/.github/workflows/docker-build-ci.yml @@ -23,19 +23,29 @@ on: - master - 'release-*' pull_request: + # Keep source/resources and shared build inputs; skip named documentation files. + paths: + - 'pom.xml' + - '.mvn/**' + - 'style/**' + - '.editorconfig' + - '.github/configs/**' + - 'hugegraph-commons/**' + - 'hugegraph-struct/**' + - 'hugegraph-pd/**' + - 'hugegraph-store/**' + - 'hugegraph-server/**' + - 'hugegraph-cluster-test/**' + - 'install-dist/**' + - 'docker/**' + - '.dockerignore' + - '.github/workflows/docker-build-ci.yml' + - '!**/README*' + - '!**/AGENTS.md' + - '!**/CLAUDE.md' jobs: - changes: - uses: ./.github/workflows/ci-scope.yml - permissions: - contents: read - pull-requests: read - with: - scope: docker - docker-bake-check: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest steps: - name: Checkout @@ -99,8 +109,6 @@ jobs: ' /tmp/hugegraph-bake.json docker-build: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/.github/workflows/pd-store-ci.yml b/.github/workflows/pd-store-ci.yml index fb9c91131f..79217cfc58 100644 --- a/.github/workflows/pd-store-ci.yml +++ b/.github/workflows/pd-store-ci.yml @@ -7,20 +7,28 @@ on: - 'release-*' - 'test-*' pull_request: + # Keep source/resources and shared build inputs; skip named documentation files. + paths: + - 'pom.xml' + - '.mvn/**' + - 'style/**' + - '.editorconfig' + - '.github/configs/**' + - 'hugegraph-commons/**' + - 'hugegraph-struct/**' + - 'hugegraph-pd/**' + - 'hugegraph-store/**' + - 'hugegraph-server/**' + - '.github/workflows/pd-store-ci.yml' + - 'docker/**' + - 'install-dist/**' + - '!**/README*' + - '!**/AGENTS.md' + - '!**/CLAUDE.md' # TODO: consider merge to one ci.yml file jobs: - changes: - uses: ./.github/workflows/ci-scope.yml - permissions: - contents: read - pull-requests: read - with: - scope: distributed - struct: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-latest env: USE_STAGE: 'false' @@ -74,8 +82,7 @@ jobs: mvn -U -ntp -pl hugegraph-struct test pd: - needs: [changes, struct] - if: needs.changes.outputs.run == 'true' + needs: struct runs-on: ubuntu-latest env: # TODO: avoid duplicated env setup in pd & store @@ -214,8 +221,7 @@ jobs: fail_ci_if_error: false store: - needs: [changes, struct] - if: needs.changes.outputs.run == 'true' + needs: struct runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. @@ -359,8 +365,7 @@ jobs: fail_ci_if_error: false hstore: - needs: [changes, struct] - if: needs.changes.outputs.run == 'true' + needs: struct runs-on: ubuntu-latest env: USE_STAGE: 'false' # Whether to include the stage repository. diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index 58a6a2c7c2..b5f5efc270 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -9,17 +9,7 @@ on: pull_request: jobs: - changes: - uses: ./.github/workflows/ci-scope.yml - permissions: - contents: read - pull-requests: read - with: - scope: server - wait-storage-shell-test: - needs: changes - if: needs.changes.outputs.run == 'true' permissions: contents: read runs-on: ubuntu-24.04 @@ -33,8 +23,6 @@ jobs: run: hugegraph-server/hugegraph-dist/src/assembly/travis/test-wait-storage.sh build-server: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ubuntu-24.04 env: USE_STAGE: 'false' # Whether to include the stage repository. @@ -190,8 +178,6 @@ jobs: fail_ci_if_error: false build-server-macos-rocksdb: - needs: changes - if: needs.changes.outputs.run == 'true' runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -272,8 +258,6 @@ jobs: fi build-server-riscv64: - needs: changes - if: needs.changes.outputs.run == 'true' uses: ./.github/workflows/riscv64-ci.yml permissions: contents: read diff --git a/docs/BUILDING.md b/docs/BUILDING.md index a0af8d7476..e21d856a8a 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -40,16 +40,13 @@ To find the Java binary in your environment, run the appropriate command for you * Windows: `for %i in (java.exe) do @echo. %~$PATH:i` -## CI change selection +## CI paths -Pull requests use `.github/workflows/ci-scope.yml` to skip unrelated build jobs. -Known documentation changes skip ordinary Maven and Docker builds; source resources -(including text fixtures), shared POMs and CI configuration still trigger relevant checks. -Shared component changes include downstream modules. Unknown paths are handled conservatively. -Dependency compilation runs for POMs, dependency inventories, packaged JARs and build configuration. +PD/Store, cluster, Docker and dependency workflows use native GitHub Actions PR +path filters. Their module inputs and shared build configuration trigger checks; +README and agent instruction files do not. Text fixtures and dependency inventories +remain included. Push runs retain their existing coverage. -Workflow triggers and required job names remain present, avoiding pending required checks. -CodeQL, license checks and dependency review remain enabled. Push, scheduled and manual runs -retain their existing coverage. Failed or incomplete file discovery falls back to running CI. - -Validate path selection locally with `node .github/scripts/test-ci-scope.cjs`. +Server, Commons, CodeQL and license workflows remain unfiltered because they +provide required checks. Skipping a required workflow by path can leave it pending. +If required checks change, revisit these filters together with `.asf.yaml`. From be4a7d492594cb2ccbef5a0be20db52db0f8cc04 Mon Sep 17 00:00:00 2001 From: imbajin Date: Thu, 17 Sep 2026 22:17:52 +0800 Subject: [PATCH 3/4] chore(ci): keep filter rationale near required checks - remove CI implementation details from the build guide - explain path-filter constraints beside required checks - keep the filtering rationale in the PR description --- .asf.yaml | 1 + docs/BUILDING.md | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.asf.yaml b/.asf.yaml index 2cc4b1d1b4..9aa07d545a 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -33,6 +33,7 @@ github: protected_branches: master: required_status_checks: + # Keep workflows providing these checks unfiltered; path skips can leave required checks pending. # strict means "Require PR to be up-to-date before merging". (enable when branch unstable) strict: false # contexts are the names of checks that must pass (now only enable the basic check) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index e21d856a8a..d99c815019 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -38,15 +38,3 @@ To build without executing tests: To find the Java binary in your environment, run the appropriate command for your operating system: * Linux/macOS: `which java` * Windows: `for %i in (java.exe) do @echo. %~$PATH:i` - - -## CI paths - -PD/Store, cluster, Docker and dependency workflows use native GitHub Actions PR -path filters. Their module inputs and shared build configuration trigger checks; -README and agent instruction files do not. Text fixtures and dependency inventories -remain included. Push runs retain their existing coverage. - -Server, Commons, CodeQL and license workflows remain unfiltered because they -provide required checks. Skipping a required workflow by path can leave it pending. -If required checks change, revisit these filters together with `.asf.yaml`. From d08f2e022deb829d63ea2415f19b643e4ab3fdb1 Mon Sep 17 00:00:00 2001 From: imbajin Date: Thu, 17 Sep 2026 22:18:06 +0800 Subject: [PATCH 4/4] chore(ci): preserve build guide original formatting --- docs/BUILDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index d99c815019..d4c807c748 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -38,3 +38,4 @@ To build without executing tests: To find the Java binary in your environment, run the appropriate command for your operating system: * Linux/macOS: `which java` * Windows: `for %i in (java.exe) do @echo. %~$PATH:i` +