Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/check_cla_ruleset.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ jobs:
python reusable_workflows/check_membership/check_external_contrib.py
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPO: ${{ github.event.repository.name }}

- name: Close Pull Request
id: close_pr
if: ${{ steps.accepts_external_contrib.outputs.accepts_contrib != 'true' }}
uses: superbrothers/close-pull-request@v3
uses: superbrothers/close-pull-request@9c18513d320d7b2c7185fb93396d0c664d5d8448 #v3
with:
comment: |
Thank you for contributing! Unfortunately this repository does not accept external contributions yet.
Expand All @@ -62,12 +62,13 @@ jobs:

We hope you understand and will come back once we accept external PRs.

— The DFINITY Foundation"""
— The DFINITY Foundation

- name: Add Label
uses: actions/github-script@v6
if: ${{ steps.accepts_external_contrib.outputs.accepts_contrib != 'false' }}
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
github.rest.issues.addLabels({
issue_number: context.issue.number,
Expand Down
68 changes: 36 additions & 32 deletions .github/workflows/internal_vs_external.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@ permissions:
pull-requests: write

jobs:
check-membership:
uses: dfinity/public-workflows/.github/workflows/check_membership.yml@main
secrets: inherit

revoke-approvals:
name: Check Revoke Approvals
runs-on: ubuntu-latest
needs: check-membership
if: ${{ needs.check-membership.outputs.is_member != 'true' && needs.check-membership.result == 'success' }}
if: github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository
steps:
- name: Dismiss Pull Request Reviews
if: ${{ ! github.event.pull_request_target.draft }}
Expand Down Expand Up @@ -54,52 +49,61 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # actor is github actions with above permissions
GH_ORG: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
PULL_NUMBER: ${{ github.event.pull_request.number }}
PULL_NUMBER: ${{ github.event.pull_request.number }}

check-external-file-changes:
name: Check Unallowed File Changes
runs-on: ubuntu-latest
needs: check-membership
if: ${{ needs.check-membership.outputs.is_member != 'true' && needs.check-membership.result == 'success' }}
if: github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository
steps:
# First check out code from public-workflows
- name: Checkout
uses: actions/checkout@v4
- name: Checkout EXTERNAL_CONTRIB_BLACKLIST from ${{ github.repository }}
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: dfinity/public-workflows
path: public-workflows
path: repo
# actions/checkout will checkout the target repo and default branch by default
# when triggered by pull_request_target. However for security reasons we want to
# be explicit here.
repository: ${{ github.repository }}
ref: ${{ github.event.repository.default_branch }}
sparse-checkout: .github/repo_policies/EXTERNAL_CONTRIB_BLACKLIST

- name: Python Setup
uses: ./public-workflows/.github/workflows/python-setup
- name: Checkout check_external_changes.py from dfinity/public-workflows
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
working-directory: public-workflows
repository: dfinity/public-workflows
path: public-workflows
sparse-checkout: reusable_workflows/repo_policies/check_external_changes.py

- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
use_rest_api: 'true'
use_rest_api: true
json: true
write_output_files: true

- name: Check External Changes
id: check-external-changes
run: |
export PYTHONPATH="$PWD/public-workflows/reusable_workflows/"
python public-workflows/reusable_workflows/repo_policies/check_external_changes.py
shell: bash
if: ${{ hashFiles('repo/.github/repo_policies/EXTERNAL_CONTRIB_BLACKLIST') != '' }}
id: check_external_changes
run: public-workflows/reusable_workflows/repo_policies/check_external_changes.py
env:
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # no actual token stored, read-only permissions
ORG: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
# populated by the action
# https://github.com/tj-actions/changed-files/blob/d03a93c0dbfac6d6dd6a0d8a5e7daff992b07449/README.md?plain=1#L569-L572
CHANGED_FILES_JSON_PATH: ".github/outputs/all_changed_and_modified_files.json"
EXTERNAL_CONTRIB_BLACKLIST_PATH: "repo/.github/repo_policies/EXTERNAL_CONTRIB_BLACKLIST"

- name: Add PR Comment
- name: Close PR
uses: actions/github-script@v7
if: ${{ failure() }}
if: ${{ !cancelled() && steps.check_external_changes.conclusion == 'failure' }}
with:
script: |
let message = "Changes made to unallowed files. "
github.rest.pulls.update({
pull_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed'
})
let message = "Closed Pull Request since changes were made to [unallowed files](${{ github.server_url }}/${{ github.repository }}/blob/${{ github.event.repository.default_branch }}/.github/repo_policies/EXTERNAL_CONTRIB_BLACKLIST).\n\n"
message += 'Please see details here: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\n\n'

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/repo_policies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Bot Policies Ruleset
on:
pull_request_target:
merge_group:
workflow_call:

jobs:
check-is-bot:
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pytest==8.3.4
# via -r requirements.in
python-dateutil==2.9.0.post0
# via github3-py
requests==2.32.3
requests==2.32.4
# via github3-py
six==1.17.0
# via python-dateutil
Expand All @@ -64,5 +64,5 @@ typing-extensions==4.12.2
# mypy
uritemplate==4.1.1
# via github3-py
urllib3==2.2.3
urllib3==2.5.0
# via requests
1 change: 1 addition & 0 deletions reusable_workflows/check_membership/check_membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"gix-bot",
"mergify[bot]",
"pr-automation-bot-public[bot]",
"pr-creation-bot-dfinity-ic[bot]",
"pr-creation-bot-dfinity[bot]",
"sa-github-api",
]
Expand Down
70 changes: 22 additions & 48 deletions reusable_workflows/repo_policies/check_external_changes.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,65 +1,39 @@
#!/usr/bin/env python3
import fnmatch
import json
import os
import sys
from pathlib import Path

import github3

from shared.utils import download_gh_file, load_env_vars
def main():
EXTERNAL_CONTRIB_BLACKLIST_PATH = os.environ['EXTERNAL_CONTRIB_BLACKLIST_PATH']

EXTERNAL_CONTRIB_BLACKLIST_PATH = ".github/repo_policies/EXTERNAL_CONTRIB_BLACKLIST"
blacklisted_patterns = [
pattern for line in Path(EXTERNAL_CONTRIB_BLACKLIST_PATH).read_text().splitlines()
if (pattern := line.split("#")[0].strip()) != ""
]

with open(os.environ['CHANGED_FILES_JSON_PATH'], 'r') as f:
changed_files = json.load(f)

def get_blacklisted_files(repo: github3.github.repo) -> list[str]:
"""
Loads the config from the repository that contains the list of blacklisted files.
"""
try:
config_file = download_gh_file(repo, EXTERNAL_CONTRIB_BLACKLIST_PATH)
except github3.exceptions.NotFoundError:
return []
blacklisted_files = [
line for line in config_file.splitlines() if line.strip() and not line.strip().startswith("#")
]
return blacklisted_files
print(f"Changed files: {changed_files}")
print(f"Blacklisted patterns: {blacklisted_patterns}")

if blacklisted_patterns == []:
print("No blacklisted patterns found.")
sys.exit(0)

def check_files_against_blacklist(changed_files: list, blacklist_files: list) -> None:
"""
Check if any changed files match the blacklist rules using glob pattern matching.
"""
violations = []
for file in changed_files:
for rule in blacklist_files:
if fnmatch.fnmatch(file, rule): # Use glob pattern matching
violations.append(file)
violations = [
file for pattern in blacklisted_patterns for file in changed_files
if fnmatch.fnmatch(file, pattern)
]

if len(violations) > 0:
print(f"No changes allowed to files: {violations}")
sys.exit(1)

else:
print("All changed files pass conditions.")


def main():
# Environment variables
REQUIRED_ENV_VARS = ["REPO", "CHANGED_FILES", "ORG", "GH_TOKEN"]
env_vars = load_env_vars(REQUIRED_ENV_VARS)

gh = github3.login(token=env_vars["GH_TOKEN"])
repo = gh.repository(owner=env_vars["ORG"], repository=env_vars["REPO"])

# Get changed files
changed_files = env_vars["CHANGED_FILES"].split()
print(f"Changed files: {changed_files}")

blacklist_files = get_blacklisted_files(repo)

if blacklist_files == []:
print("No blacklisted files found found.")
sys.exit(0)

# Check changed files against blacklist
check_files_against_blacklist(changed_files, blacklist_files)
print("All changed files pass conditions.")


if __name__ == "__main__":
Expand Down
29 changes: 0 additions & 29 deletions reusable_workflows/tests/test_external_changes.py

This file was deleted.