From e8c694f9513d5a8a44fd392cc75d98d6ea0e9903 Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Sun, 12 Jan 2025 07:39:14 -0600 Subject: [PATCH 1/4] Use App Token --- .github/workflows/update-dependencies.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index bcd11ad..827b417 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -22,7 +22,13 @@ jobs: name: Check for Vendor Updates runs-on: ubuntu-latest container: ghcr.io/frc5572/workflows/vendor-update:${{ inputs.version }} - steps: + steps: + - name: Generate a token + id: generate-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ vars.VENDOR_UPDATE_APP_ID }} + private-key: ${{ secrets.VENDOR_UPDATE_PRIVATE_KEY }} - name: Update Git run: | apk update && apk add git --update-cache @@ -33,9 +39,10 @@ jobs: git config --system --add safe.directory "*" git config --system user.name "Vendor Updater" git config --system user.email "frc5572-vendor@users.noreply.github.com" - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git remote set-url origin https://x-access-token:${{ env.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY python /app/vendor-update.py env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} BASE_BRANCH: ${{ inputs.base_branch }} REPO_PATH: ${{ github.repository }} \ No newline at end of file From d7ffc4827502300ca92eeadf9cf3d66675a0346e Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Sun, 12 Jan 2025 07:54:17 -0600 Subject: [PATCH 2/4] update app token --- .github/workflows/update-dependencies.yml | 31 +++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml index 827b417..a2f40fe 100644 --- a/.github/workflows/update-dependencies.yml +++ b/.github/workflows/update-dependencies.yml @@ -14,8 +14,6 @@ on: permissions: packages: read - contents: write - pull-requests: write # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: vendor-update-check: @@ -23,26 +21,37 @@ jobs: runs-on: ubuntu-latest container: ghcr.io/frc5572/workflows/vendor-update:${{ inputs.version }} steps: + - name: Update Git + run: | + apk update && apk add git --update-cache - name: Generate a token - id: generate-token + id: app-token uses: actions/create-github-app-token@v1 with: app-id: ${{ vars.VENDOR_UPDATE_APP_ID }} private-key: ${{ secrets.VENDOR_UPDATE_PRIVATE_KEY }} - - name: Update Git - run: | - apk update && apk add git --update-cache - name: Checkout uses: actions/checkout@v4 - - name: Run Update check + with: + token: ${{ steps.app-token.outputs.token }} + persist-credentials: false + - name: Get GitHub App User ID + id: get-user-id + run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + - name: Setup GIT run: | git config --system --add safe.directory "*" - git config --system user.name "Vendor Updater" - git config --system user.email "frc5572-vendor@users.noreply.github.com" + git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]' + git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' git remote set-url origin https://x-access-token:${{ env.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + - name: Run Update check + run: | python /app/vendor-update.py env: - GH_TOKEN: ${{ steps.generate-token.outputs.token }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} BASE_BRANCH: ${{ inputs.base_branch }} REPO_PATH: ${{ github.repository }} \ No newline at end of file From 3c4ac696e313534b030d64ca22bd26684df047af Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Sun, 12 Jan 2025 08:40:56 -0600 Subject: [PATCH 3/4] It works --- vendor-update/pr-template.j2 | 1 - vendor-update/vendor-update.py | 34 +++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/vendor-update/pr-template.j2 b/vendor-update/pr-template.j2 index 10a6252..839fe2f 100644 --- a/vendor-update/pr-template.j2 +++ b/vendor-update/pr-template.j2 @@ -1,4 +1,3 @@ -# SUMMARY The following vendor dependencies have been updated. | Vendor | Change | diff --git a/vendor-update/vendor-update.py b/vendor-update/vendor-update.py index 4265824..fcd6b82 100644 --- a/vendor-update/vendor-update.py +++ b/vendor-update/vendor-update.py @@ -19,17 +19,34 @@ GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None) BASE_BRANCH = os.getenv("BASE_BRANCH", "main") REPO_PATH = os.getenv("REPO_PATH", None) +PR_TITLE = [] if __name__ == "__main__": auth = Auth.Token(GITHUB_TOKEN) g = Github(auth=auth) repo = Repo(Path.cwd()) try: - repo.delete_head(BRANCH_NAME) + repo.git.checkout(BRANCH_NAME) + current_branch = repo.active_branch + target_branch = repo.heads[BASE_BRANCH] + rebase_branch = repo.create_head("temp_rebase_branch", target_branch) + repo.head.reference = rebase_branch + repo.head.reset(index=True, working_tree=True) + try: + repo.git.rebase(current_branch) + except exc.GitCommandError as e: + # Handle rebase conflicts if any + print("Rebase conflicts occurred. Resolve them manually.") + print(e) + else: + # Delete the original branch + repo.delete_head(current_branch) + # Rename the rebased branch to the original branch name + rebase_branch.rename(current_branch) + # Update the remote branch (if needed) + # repo.remotes.origin.push(force=True) except exc.GitCommandError: - pass - new_branch = repo.create_head(BRANCH_NAME) - new_branch.checkout(force=True) + repo.git.checkout('-b', BRANCH_NAME) print("Checking for WPILIB Updates") update_wpilib = False @@ -57,6 +74,7 @@ "new_version": wpilib_latest_version, } ) + PR_TITLE.append("WPILib") else: print("No new version of WPILIB.") print("Checking for Vendor Dep Updates") @@ -94,12 +112,13 @@ modified_deps = [x for x in untracked + diffs if x.startswith("vendordeps")] if len(modified_deps) > 0: repo.git.add("vendordeps/*") + PR_TITLE.append("Vendor Dependency") else: print("No vendor updates") if len(modified_deps) == 0 and not update_wpilib: sys.exit(0) - repo.index.commit("Updating Vendor Dependencies and WPILIB") + repo.index.commit(f"Updating {', '.join([x.get('name') for x in UPDATED_DEPS])}") repo.git.push("--force", "--set-upstream", "origin", repo.head.ref) gh_repo = g.get_repo(REPO_PATH) @@ -108,8 +127,9 @@ ) with open(SCRIPT_PATH.joinpath("pr-template.j2")) as f: body = Template(f.read()).render(deps=UPDATED_DEPS) + title = f"{" and ".join(PR_TITLE)} Updates" if pulls.totalCount == 0: - gh_repo.create_pull(base=BASE_BRANCH, head=BRANCH_NAME, title="Vendor Dependency Updates", body=body, draft=True) + gh_repo.create_pull(base=BASE_BRANCH, head=BRANCH_NAME, title=title, body=body, draft=True) elif pulls.totalCount == 1: pull: PullRequest = pulls[0] - pull.edit(body=body) + pull.edit(body=body, title=title) From e2622bc0f493f1015cdd039cef81e80b2d7fc45a Mon Sep 17 00:00:00 2001 From: Alex Resnick Date: Sun, 12 Jan 2025 09:12:34 -0600 Subject: [PATCH 4/4] update template --- .vscode/settings.json | 15 +++++++++------ vendor-update/pr-template.j2 | 4 +++- vendor-update/vendor-update.py | 12 ++++++++---- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ce2b961..9d73058 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,11 @@ { - "editor.codeActionsOnSave": { - "source.organizeImports": "explicit" - }, - "editor.formatOnSave": true, - "editor.formatOnPaste": true, - "terminal.integrated.defaultProfile.windows": "Git Bash" + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "terminal.integrated.defaultProfile.windows": "Git Bash", + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + } } \ No newline at end of file diff --git a/vendor-update/pr-template.j2 b/vendor-update/pr-template.j2 index 839fe2f..de9ad6b 100644 --- a/vendor-update/pr-template.j2 +++ b/vendor-update/pr-template.j2 @@ -4,4 +4,6 @@ The following vendor dependencies have been updated. |---|---| {% for item in deps -%} | {{ item.name }} | {{ item.old_version }} -> {{ item.new_version }} | -{% endfor %} \ No newline at end of file +{% endfor %} + +- [ ] This PR has been deployed and tested to the robot to confirm functionality? \ No newline at end of file diff --git a/vendor-update/vendor-update.py b/vendor-update/vendor-update.py index fcd6b82..dde40b3 100644 --- a/vendor-update/vendor-update.py +++ b/vendor-update/vendor-update.py @@ -21,6 +21,7 @@ REPO_PATH = os.getenv("REPO_PATH", None) PR_TITLE = [] + if __name__ == "__main__": auth = Auth.Token(GITHUB_TOKEN) g = Github(auth=auth) @@ -44,9 +45,8 @@ # Rename the rebased branch to the original branch name rebase_branch.rename(current_branch) # Update the remote branch (if needed) - # repo.remotes.origin.push(force=True) except exc.GitCommandError: - repo.git.checkout('-b', BRANCH_NAME) + repo.git.checkout("-b", BRANCH_NAME) print("Checking for WPILIB Updates") update_wpilib = False @@ -63,7 +63,9 @@ if parse(wpilib_latest_version) > parse(wpilib_version): print(f"New WPILIB Version: {wpilib_latest_version}. Updating build.gradle.") with build_gradle.open(mode="w", encoding="utf-8") as f: - new_build = re.sub(WPILIB_REGEX, rf'\1"{wpilib_latest_version}"', build_file) + new_build = re.sub( + WPILIB_REGEX, rf'\1"{wpilib_latest_version}"', build_file + ) f.write(new_build) update_wpilib = True repo.git.add("build.gradle") @@ -129,7 +131,9 @@ body = Template(f.read()).render(deps=UPDATED_DEPS) title = f"{" and ".join(PR_TITLE)} Updates" if pulls.totalCount == 0: - gh_repo.create_pull(base=BASE_BRANCH, head=BRANCH_NAME, title=title, body=body, draft=True) + gh_repo.create_pull( + base=BASE_BRANCH, head=BRANCH_NAME, title=title, body=body, draft=True + ) elif pulls.totalCount == 1: pull: PullRequest = pulls[0] pull.edit(body=body, title=title)