From 57b29601170bd7fee477723402b03e1a4f77357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mislav=20Marohni=C4=87?= Date: Sun, 26 Dec 2021 13:28:26 +0100 Subject: [PATCH] Add `push-to` option to point to shared forks (#30) Fixes #20 --- README.md | 2 + action.yml | 4 +- src/edit-github-blob-test.ts | 76 ++++++++++++++++++++++++++++++++++++ src/edit-github-blob.ts | 12 +++++- src/main.ts | 7 ++++ 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8efa5e7..63d37e1 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ archive for this release. * `homebrew-tap`: the repository where the formula should be updated. Defaults to `Homebrew/homebrew-core`. +* `push-to`: a specific fork of `homebrew-tap` where the edit should be pushed to. Defaults to creating or reusing a personal fork of the owner of COMMITTER_TOKEN. + * `base-branch`: the branch name in the `homebrew-tap` repository where the formula should be updated. Defaults to the main branch. diff --git a/action.yml b/action.yml index c48bd22..dff8dae 100644 --- a/action.yml +++ b/action.yml @@ -18,8 +18,10 @@ inputs: homebrew-tap: description: The repository where the formula should be updated default: Homebrew/homebrew-core + push-to: + description: An existing fork of the homebrew-tap repository where the edit should be pushed to (defaults to creating or reusing a personal fork) base-branch: - description: The branch name in the homebrew-tap repository where the formula should be updated + description: The branch name in the homebrew-tap repository to update the formula in create-pullrequest: description: Set to a boolean value to either force or prohibit making a pull request to homebrew-tap commit-message: diff --git a/src/edit-github-blob-test.ts b/src/edit-github-blob-test.ts index f64362a..385fc66 100644 --- a/src/edit-github-blob-test.ts +++ b/src/edit-github-blob-test.ts @@ -147,3 +147,79 @@ test('edit-github-blob via pull request', async (t) => { }) t.is('https://github.com/OWNER/REPO/pull/123', url) }) + +test('edit-github-blob with pushTo', async (t) => { + var newBranchName: string + const stubbedFetch = function (url: string, options: fetchOptions) { + function route(method: string, path: string): boolean { + return ( + method.toUpperCase() === options.method.toUpperCase() && + `https://api.github.com/${path}` === url + ) + } + + if (route('GET', 'repos/OWNER/REPO')) { + return replyJSON(200, { + default_branch: 'main', + permissions: { push: false }, + }) + } else if (route('GET', 'repos/OWNER/REPO/branches/main')) { + return replyJSON(200, { + commit: { sha: 'COMMITSHA' }, + protected: false, + }) + } else if (route('POST', 'repos/FORKOWNER/REPO/merge-upstream')) { + const payload = JSON.parse(options.body || '') + t.is('main', payload.branch) + return replyJSON(409, {}) + } else if (route('POST', 'repos/FORKOWNER/REPO/git/refs')) { + const payload = JSON.parse(options.body || '') + t.regex(payload.ref, /^refs\/heads\/update-test\.rb-\d+$/) + newBranchName = payload.ref.replace('refs/heads/', '') + t.is('COMMITSHA', payload.sha) + return replyJSON(201, {}) + } else if ( + route( + 'GET', + `repos/FORKOWNER/REPO/contents/formula%2Ftest.rb?ref=${newBranchName}` + ) + ) { + return replyJSON(200, { + content: Buffer.from(`old content`).toString('base64'), + }) + } else if ( + route('PUT', 'repos/FORKOWNER/REPO/contents/formula%2Ftest.rb') + ) { + const payload = JSON.parse(options.body || '') + t.is(newBranchName, payload.branch) + t.is('Update formula/test.rb', payload.message) + t.is( + 'OLD CONTENT', + Buffer.from(payload.content, 'base64').toString('utf8') + ) + return replyJSON(200, { + commit: { html_url: 'https://github.com/OWNER/REPO/commit/NEWSHA' }, + }) + } else if (route('POST', 'repos/OWNER/REPO/pulls')) { + const payload = JSON.parse(options.body || '') + t.is('main', payload.base) + t.is(`FORKOWNER:${newBranchName}`, payload.head) + t.is('Update formula/test.rb', payload.title) + t.is('', payload.body) + return replyJSON(201, { + html_url: 'https://github.com/OWNER/REPO/pull/123', + }) + } + throw `not stubbed: ${options.method} ${url}` + } + + const url = await editGithubBlob({ + apiClient: api('ATOKEN', { fetch: stubbedFetch, logRequests: false }), + owner: 'OWNER', + repo: 'REPO', + pushTo: { owner: 'FORKOWNER', repo: 'REPO' }, + filePath: 'formula/test.rb', + replace: (oldContent) => oldContent.toUpperCase(), + }) + t.is('https://github.com/OWNER/REPO/pull/123', url) +}) diff --git a/src/edit-github-blob.ts b/src/edit-github-blob.ts index d330405..6708379 100644 --- a/src/edit-github-blob.ts +++ b/src/edit-github-blob.ts @@ -29,6 +29,10 @@ export type Options = { apiClient: API replace: (oldContent: string) => string commitMessage?: string + pushTo?: { + owner: string + repo: string + } makePR?: boolean } @@ -50,8 +54,12 @@ export default async function (params: Options): Promise { }) const needsFork = - repoRes.data.permissions == null || !repoRes.data.permissions.push - if (needsFork) { + repoRes.data.permissions == null || + !repoRes.data.permissions.push || + params.pushTo != null + if (params.pushTo != null) { + headRepo = params.pushTo + } else if (needsFork) { const res = await Promise.all([ api.repos.createFork(baseRepo), api.users.getAuthenticated(), diff --git a/src/main.ts b/src/main.ts index 2cc6313..906ef32 100644 --- a/src/main.ts +++ b/src/main.ts @@ -65,6 +65,12 @@ export async function prepareEdit( })(ctx.ref) const [owner, repo] = getInput('homebrew-tap', { required: true }).split('/') + var pushTo: { owner: string; repo: string } | undefined + const pushToSpec = getInput('push-to') + if (pushToSpec) { + const [pushToOwner, pushToRepo] = pushToSpec.split('/') + pushTo = { owner: pushToOwner, repo: pushToRepo } + } const formulaName = getInput('formula-name') || ctx.repo.repo.toLowerCase() const branch = getInput('base-branch') const filePath = getInput('formula-path') || `Formula/${formulaName}.rb` @@ -117,6 +123,7 @@ export async function prepareEdit( branch, filePath, commitMessage, + pushTo, makePR, replace(oldContent: string) { return removeRevisionLine(replaceFields(oldContent, replacements))