Github Actions で他のリポジトリからの変更通知を受け取ってPRを作成する Workflow
やりたいこと
- リポジトリ A は npm package を publish したことを リポジトリ B に通知したい
- リポジトリ B は 通知を受けたら package.json を更新する PR を作成したい
個人のリポジトリでの依存ならこの需要は少ないかもしれませんが、社内でリポジトリを分割してたりすると、更新漏れが発生したりします。それを機械的に防ぎたい。でも手動マージはしたくないのでPR作成まで。そのぐらいの温度感を実現したい、という感じ。
また、リポジトリ B は リポジトリ A の通知によらず、手動でそのタスクを実行できるようにしておきたいです。
(ネタバレすると、先に手動のタスクがあって、その上でリポジトリ間通知を実装しました)
(構成要素とレシピ紹介がメインで、コード自体は動いてたコードからの切り貼りなので、そのままは動かないかも。後で要確認)
実装方法
GitHub Actions の Trigger として、 Workflow Dispatch と Repository Dispatch があります。Workflow Dispatch は Actions の管理画面から手動での実行、 Repository Dispatch は GitHub API からの通知を受けてトリガーを実行します。
どちらも引数を取れます。Workflow Dispatch なら管理画面からの入力、Repositry Dispatch なら client_payload の引数で渡します。
通知を受け取って package.json を更新する側の workflow
.github/workflows/update-packages.yaml
name: Update Packages
on:
repository_dispatch:
types: [update-packages] # with client_payload.packages
workflow_dispatch:
inputs:
packages:
description: ''
required: true
default: ''
jobs:
update-packages:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: setup Node
uses: actions/setup-node@v1
- name: Install
run: npm install
- Update packages by workflow_dispatch
if: ${{ github.event.inputs.packages != null }}
run: npm update ${{ github.event.inputs.packages }}
- Update packages by repository_dispatch
if: ${{ github.event.client_payload.packages != null }}
run: npm update ${{ github.event.client_payload.packages }}
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'Update packages'
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: feature/update-package
branch-suffix: timestamp
delete-branch: true
title: 'Update Packages by CI'
body: |
@${{ github.actor }}
```
${{ github.event.inputs.packages }}
${{ github.event.client_payload.packages }}
```
- name: Check Pull Request
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
通知する側の workflow
.github/workflows/publish-and-notify.yaml
Github Private Token を発行して、 ↑ で定義した Repository に向けて次の curl を叩くことで更新できます。
Repo 権限が必要です。
curl -v -H "Authorization: token <GITHUB_PRIVATE_TOKEN>" -H "Accept: application/vnd.github.everest-preview+json" "https://api.github.com/repos/<name>/<repo>/dispatches" -d '{"event_type": "update-packages", "client_payload": {"packages": "lodash@4.17.20"}}'
これを repository_dispatch したい側の merge trigger で、 repostitory dispatch を実行します。
注意点として、 secrets.GITHUB_TOKEN は権限が足りず repository_dispatch がトリガーできません。トークンを発行する必要があります。
今回は github package registry に publish してます。npm トークンが不要で、社内のリポジトリ間という事情です。 npm に publish したい場合、 npm の token が必要です。
Publish to npm · Actions · GitHub Marketplace
name: publish-and-dispatch
on:
push:
branches:
- master
jobs:
release:
name: Setup
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v2
- name: setup Node
uses: actions/setup-node@v1
with:
registry-url: "https://npm.pkg.github.com"
- name: install
run: npm install
- name: build
run: npm run build
- name: publish
run: |
npx can-npm-publish --verbose && npm publish || echo "Does not publish"
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: package-version-to-git-tag
uses: pkgdeps/action-package-version-to-git-tag@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
github_repo: ${{ github.repository }}
git_commit_sha: ${{ github.sha }}
git_tag_prefix: "v"
- name: dispatch update-packages
uses: peter-evans/repository-dispatch@v1
with:
repository: github_name/repo
token: ${{ secrets.GITHUB_PERSONAL_TOKEN }}
event-type: update-pkgs
secrets に GITHUB_PERSONAL_TOKEN を設定してあるのを前提としてます。dispatch 対象は自分ではなく、対象です
色々サボってて、本当は変更があったときだけ publish したいんですが、それはまあなんとでもなるので…
Discussion