From 5227d812735926740761770a4981541935d0c53c Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Mon, 23 Mar 2026 16:06:11 -0700 Subject: [PATCH 1/4] use v7 --- .github/workflows/open-api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/open-api.yml b/.github/workflows/open-api.yml index 41d52d1768fc..92948894d452 100644 --- a/.github/workflows/open-api.yml +++ b/.github/workflows/open-api.yml @@ -46,7 +46,7 @@ jobs: steps: - uses: actions/checkout@v6 - name: Install uv - uses: astral-sh/setup-uv@5a095e7a2014a4212f075830d4f7277575a9d098 + uses: astral-sh/setup-uv@v7 - name: Install dependencies working-directory: ./open-api run: make install From f6c8e582efa707b6f0e9e9fb5948937bb96bb6da Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Tue, 24 Mar 2026 21:04:19 -0700 Subject: [PATCH 2/4] add asf allowlist check --- .github/scripts/check_asf_allowlist.py | 128 ++++++++++++++++++++++ .github/workflows/asf-allowlist-check.yml | 50 +++++++++ 2 files changed, 178 insertions(+) create mode 100644 .github/scripts/check_asf_allowlist.py create mode 100644 .github/workflows/asf-allowlist-check.yml diff --git a/.github/scripts/check_asf_allowlist.py b/.github/scripts/check_asf_allowlist.py new file mode 100644 index 000000000000..51ed35abdfc2 --- /dev/null +++ b/.github/scripts/check_asf_allowlist.py @@ -0,0 +1,128 @@ +# 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. + +"""Check that all GitHub Actions uses: refs are on the ASF allowlist. + +Usage: + python3 .github/scripts/check_asf_allowlist.py + +The allowlist is the approved_patterns.yml file from +https://github.com/apache/infrastructure-actions/blob/main/approved_patterns.yml. + +Exits with code 1 if any action ref is not allowlisted. +""" + +import fnmatch +import glob +import sys + +import yaml + +# actions/*, github/*, apache/* are implicitly trusted by GitHub/ASF +# https://github.com/apache/infrastructure-actions/blob/main?tab=readme-ov-file#management-of-organization-wide-github-actions-allow-list +TRUSTED_OWNERS = {"actions", "github", "apache"} + +# Glob pattern for YAML files to scan for action refs +GITHUB_YAML_GLOB = ".github/**/*.yml" + +# Prefixes that indicate local or non-GitHub refs (not subject to allowlist) +LOCAL_REF_PREFIXES = ("./",) + +# YAML key that references a GitHub Action +USES_KEY = "uses" + + +def find_action_refs(node): + """Recursively find all `uses:` values from a parsed YAML tree.""" + if isinstance(node, dict): + for key, value in node.items(): + if key == USES_KEY and isinstance(value, str): + yield value + else: + yield from find_action_refs(value) + elif isinstance(node, list): + for item in node: + yield from find_action_refs(item) + + +def collect_action_refs(): + """Collect all third-party action refs from YAML files under .github/. + + Returns a dict mapping each action ref to the list of file paths that use it. + Local refs (./) are excluded. + """ + action_refs = {} + for filepath in sorted(glob.glob(GITHUB_YAML_GLOB, recursive=True)): + with open(filepath) as f: + content = yaml.safe_load(f) + if not content: + continue + for ref in find_action_refs(content): + if ref.startswith(LOCAL_REF_PREFIXES): + continue + action_refs.setdefault(ref, []).append(filepath) + return action_refs + + +def load_allowlist(allowlist_path): + """Load the ASF approved_patterns.yml file. + + The file is a flat YAML list of entries like: + - owner/action@ (exact SHA match) + - owner/action@* (any ref allowed) + - golangci/*@* (any repo under owner, any ref) + + Python's fnmatch.fnmatch matches "/" with "*" (unlike shell globs), + so these patterns work directly without transformation. + """ + with open(allowlist_path) as f: + return yaml.safe_load(f) + + +def is_allowed(action_ref, allowlist): + """Check whether a single action ref is allowed.""" + if action_ref.split("/")[0] in TRUSTED_OWNERS: + return True + return any(fnmatch.fnmatch(action_ref, pattern) for pattern in allowlist) + + +def main(): + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} ", file=sys.stderr) + sys.exit(2) + + allowlist_path = sys.argv[1] + allowlist = load_allowlist(allowlist_path) + action_refs = collect_action_refs() + + violations = [] + for action_ref, filepaths in sorted(action_refs.items()): + if not is_allowed(action_ref, allowlist): + for filepath in filepaths: + violations.append(f"{filepath}\t{action_ref}") + + if violations: + print("::error::Found action(s) not on the ASF allowlist:") + for violation in violations: + print(violation) + sys.exit(1) + else: + print(f"All {len(action_refs)} unique action refs are on the ASF allowlist") + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/asf-allowlist-check.yml b/.github/workflows/asf-allowlist-check.yml new file mode 100644 index 000000000000..4cf984d13c63 --- /dev/null +++ b/.github/workflows/asf-allowlist-check.yml @@ -0,0 +1,50 @@ +# 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: "ASF Allowlist Check" + +on: + pull_request: + paths: + - ".github/**" + push: + branches: + - main + paths: + - ".github/**" + workflow_dispatch: + +permissions: + contents: read + +jobs: + asf-allowlist-check: + name: "Check actions against ASF allowlist" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + persist-credentials: false + - name: Download ASF approved patterns + shell: bash + run: | + curl -sSfL \ + "https://raw.githubusercontent.com/apache/infrastructure-actions/main/approved_patterns.yml" \ + -o /tmp/approved_patterns.yml + - name: Verify all action refs are allowlisted + shell: bash + run: python3 .github/scripts/check_asf_allowlist.py /tmp/approved_patterns.yml \ No newline at end of file From 3c52b63ac5c9092646cd329a16ffd91d77beb5f7 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 25 Mar 2026 10:21:04 -0700 Subject: [PATCH 3/4] Revert "add asf allowlist check" This reverts commit f6c8e582efa707b6f0e9e9fb5948937bb96bb6da. --- .github/scripts/check_asf_allowlist.py | 128 ---------------------- .github/workflows/asf-allowlist-check.yml | 50 --------- 2 files changed, 178 deletions(-) delete mode 100644 .github/scripts/check_asf_allowlist.py delete mode 100644 .github/workflows/asf-allowlist-check.yml diff --git a/.github/scripts/check_asf_allowlist.py b/.github/scripts/check_asf_allowlist.py deleted file mode 100644 index 51ed35abdfc2..000000000000 --- a/.github/scripts/check_asf_allowlist.py +++ /dev/null @@ -1,128 +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. - -"""Check that all GitHub Actions uses: refs are on the ASF allowlist. - -Usage: - python3 .github/scripts/check_asf_allowlist.py - -The allowlist is the approved_patterns.yml file from -https://github.com/apache/infrastructure-actions/blob/main/approved_patterns.yml. - -Exits with code 1 if any action ref is not allowlisted. -""" - -import fnmatch -import glob -import sys - -import yaml - -# actions/*, github/*, apache/* are implicitly trusted by GitHub/ASF -# https://github.com/apache/infrastructure-actions/blob/main?tab=readme-ov-file#management-of-organization-wide-github-actions-allow-list -TRUSTED_OWNERS = {"actions", "github", "apache"} - -# Glob pattern for YAML files to scan for action refs -GITHUB_YAML_GLOB = ".github/**/*.yml" - -# Prefixes that indicate local or non-GitHub refs (not subject to allowlist) -LOCAL_REF_PREFIXES = ("./",) - -# YAML key that references a GitHub Action -USES_KEY = "uses" - - -def find_action_refs(node): - """Recursively find all `uses:` values from a parsed YAML tree.""" - if isinstance(node, dict): - for key, value in node.items(): - if key == USES_KEY and isinstance(value, str): - yield value - else: - yield from find_action_refs(value) - elif isinstance(node, list): - for item in node: - yield from find_action_refs(item) - - -def collect_action_refs(): - """Collect all third-party action refs from YAML files under .github/. - - Returns a dict mapping each action ref to the list of file paths that use it. - Local refs (./) are excluded. - """ - action_refs = {} - for filepath in sorted(glob.glob(GITHUB_YAML_GLOB, recursive=True)): - with open(filepath) as f: - content = yaml.safe_load(f) - if not content: - continue - for ref in find_action_refs(content): - if ref.startswith(LOCAL_REF_PREFIXES): - continue - action_refs.setdefault(ref, []).append(filepath) - return action_refs - - -def load_allowlist(allowlist_path): - """Load the ASF approved_patterns.yml file. - - The file is a flat YAML list of entries like: - - owner/action@ (exact SHA match) - - owner/action@* (any ref allowed) - - golangci/*@* (any repo under owner, any ref) - - Python's fnmatch.fnmatch matches "/" with "*" (unlike shell globs), - so these patterns work directly without transformation. - """ - with open(allowlist_path) as f: - return yaml.safe_load(f) - - -def is_allowed(action_ref, allowlist): - """Check whether a single action ref is allowed.""" - if action_ref.split("/")[0] in TRUSTED_OWNERS: - return True - return any(fnmatch.fnmatch(action_ref, pattern) for pattern in allowlist) - - -def main(): - if len(sys.argv) != 2: - print(f"Usage: {sys.argv[0]} ", file=sys.stderr) - sys.exit(2) - - allowlist_path = sys.argv[1] - allowlist = load_allowlist(allowlist_path) - action_refs = collect_action_refs() - - violations = [] - for action_ref, filepaths in sorted(action_refs.items()): - if not is_allowed(action_ref, allowlist): - for filepath in filepaths: - violations.append(f"{filepath}\t{action_ref}") - - if violations: - print("::error::Found action(s) not on the ASF allowlist:") - for violation in violations: - print(violation) - sys.exit(1) - else: - print(f"All {len(action_refs)} unique action refs are on the ASF allowlist") - - -if __name__ == "__main__": - main() diff --git a/.github/workflows/asf-allowlist-check.yml b/.github/workflows/asf-allowlist-check.yml deleted file mode 100644 index 4cf984d13c63..000000000000 --- a/.github/workflows/asf-allowlist-check.yml +++ /dev/null @@ -1,50 +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: "ASF Allowlist Check" - -on: - pull_request: - paths: - - ".github/**" - push: - branches: - - main - paths: - - ".github/**" - workflow_dispatch: - -permissions: - contents: read - -jobs: - asf-allowlist-check: - name: "Check actions against ASF allowlist" - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - persist-credentials: false - - name: Download ASF approved patterns - shell: bash - run: | - curl -sSfL \ - "https://raw.githubusercontent.com/apache/infrastructure-actions/main/approved_patterns.yml" \ - -o /tmp/approved_patterns.yml - - name: Verify all action refs are allowlisted - shell: bash - run: python3 .github/scripts/check_asf_allowlist.py /tmp/approved_patterns.yml \ No newline at end of file From b2be390fe00951c5971390121b782a802f174190 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 25 Mar 2026 10:23:17 -0700 Subject: [PATCH 4/4] use apache infra's github action to check asf allowlist --- .github/workflows/asf-allowlist-check.yml | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/asf-allowlist-check.yml diff --git a/.github/workflows/asf-allowlist-check.yml b/.github/workflows/asf-allowlist-check.yml new file mode 100644 index 000000000000..18bc2c3d33b7 --- /dev/null +++ b/.github/workflows/asf-allowlist-check.yml @@ -0,0 +1,37 @@ +# +# 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: "ASF Allowlist Check" +on: + pull_request: + paths: + - '.github/**' + +permissions: + contents: read + +jobs: + allowlist-check: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + # TODO: pin to @main after https://github.com/apache/infrastructure-actions/pull/587 is merged + - uses: apache/infrastructure-actions/allowlist-check@aa2e2255f589df470b41dc8ed27fd06f753cac9e