Open PRs in Ethereum plugins to update SDK #4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
name: Open PRs in Ethereum plugins to update SDK | |
on: | |
workflow_dispatch: | |
# TODO add auto trigger once finalized | |
jobs: | |
build-repositories-matrix: | |
name: Build repo matrix | |
runs-on: ubuntu-latest | |
env: | |
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} | |
steps: | |
- name: List plugin repositories | |
id: list-repos | |
run: | | |
# Retrieve the list of repositories from LedgerHQ organization | |
raw_repo_list=$(gh repo list LedgerHQ -L 2000 \ | |
--json name \ | |
--json isPrivate \ | |
--json isArchived \ | |
--jq '.[] | select(.isPrivate == false and .isArchived == false and select(.name | startswith("app-plugin-"))) | .name') | |
# Format the repository list as a JSON array | |
formatted_repo_list="[" | |
while IFS= read -r repo; do | |
formatted_repo_list+="\"$repo\", " | |
done < <(echo "$raw_repo_list") | |
formatted_repo_list=${formatted_repo_list%%, }"]" | |
echo "Formatted Repository List: $formatted_repo_list" | |
# Set output | |
echo "repo_list=$formatted_repo_list" >> $GITHUB_OUTPUT | |
outputs: | |
repo-matrix: ${{ steps.list-repos.outputs.repo_list }} | |
get-sdk-ref: | |
name: Get latest SDK reference | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout SDK repository | |
uses: actions/checkout@v3 | |
with: | |
repository: LedgerHQ/ethereum-plugin-sdk | |
ref: develop | |
- name: Retrieve SDK reference | |
id: get-hash | |
run: | | |
# Get the short SHA reference of the latest commit in the SDK repository | |
sdk_ref=$(git rev-parse --short HEAD) | |
echo "SDK Reference: $sdk_ref" | |
# Set output | |
echo "sdk_ref=$sdk_ref" >> $GITHUB_OUTPUT | |
outputs: | |
sdk_ref: ${{ steps.get-hash.outputs.sdk_ref }} | |
open-issue: | |
name: Open SDK update summary issue | |
runs-on: ubuntu-latest | |
needs: get-sdk-ref | |
env: | |
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} | |
steps: | |
- name: Create 'auto' label if missing | |
run: | | |
if [[ -z $(gh label list --repo ${{ github.repository }} --search auto) ]]; then | |
gh label create 'auto' --repo ${{ github.repository }} --color 'b4a8d1' --description 'Automatically created' | |
fi | |
- name: Open SDK Update Issue | |
id: open-issue | |
run: | | |
# Create a new issue with the SDK reference in the SDK repository | |
issue_url=$(gh issue create \ | |
--repo ${{ github.repository }} \ | |
--label auto \ | |
--title "Bumping Eth plugin SDK to latest version ${{ needs.get-sdk-ref.outputs.sdk_ref }}" \ | |
--body "Placeholder") | |
echo "Issue URL: $issue_url" | |
# Set output | |
echo "issue_url=$issue_url" >> $GITHUB_OUTPUT | |
outputs: | |
issue_url: ${{ steps.open-issue.outputs.issue_url }} | |
open-prs: | |
name: Open pull requests | |
runs-on: ubuntu-latest | |
needs: [build-repositories-matrix, open-issue, get-sdk-ref] | |
strategy: | |
fail-fast: false | |
matrix: | |
repo: ${{ fromJSON(needs.build-repositories-matrix.outputs.repo-matrix) }} | |
env: | |
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} | |
steps: | |
- name: Checkout plugin repository | |
uses: actions/checkout@v3 | |
with: | |
repository: LedgerHQ/${{ matrix.repo }} | |
submodules: recursive | |
ref: develop | |
# by default the action uses fetch-depth = 1, which creates | |
# shallow repositories from which we can't push | |
fetch-depth: 0 | |
# needed, else the push inside the action will use default credentials | |
# instead of provided ones | |
persist-credentials: false | |
- name: Update submodule | |
run: | | |
cd ethereum-plugin-sdk/ | |
git checkout ${{ needs.get-sdk-ref.outputs.sdk_ref }} | |
- name: Commit changes | |
id: commit-changes | |
run: | | |
# Set credentials for commit creation | |
git config --global user.name "github-actions[bot]" | |
git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
# Branch name and title will be unique by design | |
branch_name="auto/bump_sdk_to_${{ needs.get-sdk-ref.outputs.sdk_ref }}" | |
title="[auto-update] Bump SDK to latest develop version ${{ needs.get-sdk-ref.outputs.sdk_ref }}" | |
echo "Branch Name: $branch_name" | |
echo "Title: $title" | |
git status | |
git commit -am "$title" | |
# Set output | |
echo "title=$title" >> $GITHUB_OUTPUT | |
echo "branch_name=$branch_name" >> $GITHUB_OUTPUT | |
- name: Push commit | |
uses: ad-m/github-push-action@master | |
with: | |
github_token: ${{ secrets.CI_BOT_TOKEN }} | |
branch: ${{ steps.commit-changes.outputs.branch_name }} | |
repository: LedgerHQ/${{ matrix.repo }} | |
force: true | |
- name: Create 'auto' label if missing | |
run: | | |
if [[ -z $(gh label list --search auto) ]]; then | |
gh label create 'auto' --color 'b4a8d1' --description 'Automatically created' | |
fi | |
- name: Create pull request and commment on SDK issue | |
run: | | |
# Github limits the number of possible PR being opened in a given time window. | |
# The limits are 20 creation per minute and 150 per hour. | |
# As suggested in the Github documentation, put a sleep between each POST call | |
# 3 seconds should be sufficient but let's sleep 4 seconds just in case. | |
sleep $((4 * ${{ strategy.job-index }})) | |
# Create the PR with a placeholder body. Will be consolidated at a later step | |
pr_url=$(gh pr create \ | |
--base 'develop' \ | |
--head '${{ steps.commit-changes.outputs.branch_name }}' \ | |
--label 'auto' \ | |
--title '${{ steps.commit-changes.outputs.title }}' \ | |
--body 'Created by a Github workflow') | |
echo "Pull request URL: $pr_url" | |
# Log the url of the PR in the issue on SDK side. We'll collect them from the issue later | |
gh issue comment "${{ needs.open-issue.outputs.issue_url }}" --body "OPENED $pr_url" | |
clean-issue: | |
name: Clean SDK update summary issue | |
runs-on: ubuntu-latest | |
needs: [get-sdk-ref, open-issue, open-prs] | |
env: | |
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} | |
steps: | |
- name: Collect all comments on the SDK issue | |
run: | | |
# Get the full text of the issue: metadata + title + rich comments | |
content="$(gh issue view --comments "${{ needs.open-issue.outputs.issue_url }}")" | |
# New header of the issue body | |
header="Bumping Ethereum plugin SDK to latest version ${{ needs.get-sdk-ref.outputs.sdk_ref }} for all Ethereum plugins:" | |
# Filter the full text of the issue to collect only the PR urls | |
lines="" | |
while IFS= read -r line; do | |
if [[ "$line" =~ "OPENED" ]]; then | |
lines+=$(echo "$line" | cut -d ' ' -f2)$'\n' | |
fi | |
done < <(echo "$content") | |
# Use print to resolve the '\n' chars | |
new_body="$(printf "$header\n$lines")" | |
echo "New issue body: $new_body" | |
# Set the consolidated body of the issue | |
gh issue edit "${{ needs.open-issue.outputs.issue_url }}" --body "$new_body" | |
- name: Clean comments on the SDK issue | |
run: | | |
# gh api uses id instead of url | |
issue_id="$(basename "${{ needs.open-issue.outputs.issue_url }}")" | |
# Get url of all comments on the issue | |
comment_urls="$(gh api "repos/${{ github.repository }}/issues/${issue_id}/comments" --jq '.[].url')" | |
# Delete each comment using the Github REST api | |
while IFS= read -r url; do | |
echo "Deleting comment: $comment_urls" | |
gh api -X DELETE "$url" | |
done < <(echo "$comment_urls") |