Skip to content

Commit

Permalink
Merge branch 'main' into v1
Browse files Browse the repository at this point in the history
  • Loading branch information
mislav committed Dec 23, 2021
2 parents 48abd3d + 0104f12 commit c901481
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 7 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"@actions/github": "^5.0.0",
"@octokit/core": "^3.5.1",
"@octokit/plugin-request-log": "^1.0.3",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
"@octokit/plugin-rest-endpoint-methods": "^5.13.0",
"@octokit/request-error": "^2.1.0"
},
"devDependencies": {
"@types/node": "^14.14.25",
Expand Down
6 changes: 5 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ const GitHub = Octokit.plugin(restEndpointMethods, requestLog).defaults({

export type API = InstanceType<typeof GitHub>

export default function (token: string, options?: { fetch?: any }): API {
export default function (
token: string,
options?: { logRequests?: boolean; fetch?: any }
): API {
return new GitHub({
request: { fetch: options && options.fetch },
auth: `token ${token}`,
log: {
info(msg: string) {
if (options?.logRequests === false) return
return console.info(msg)
},
debug(msg: string) {
Expand Down
149 changes: 149 additions & 0 deletions src/edit-github-blob-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import test from 'ava'
import api from './api'
import { Response } from 'node-fetch'
import editGithubBlob from './edit-github-blob'

type fetchOptions = {
method: string
body: string | null
}

function replyJSON(status: number, body: any): Promise<Response> {
return Promise.resolve(
new Response(JSON.stringify(body), {
status,
headers: {
'Content-Type': 'application/json',
},
})
)
}

test('edit-github-blob direct push', async (t) => {
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: true },
})
} else if (route('GET', 'repos/OWNER/REPO/branches/main')) {
return replyJSON(200, {
commit: { sha: 'COMMITSHA' },
protected: false,
})
} else if (
route('GET', 'repos/OWNER/REPO/contents/formula%2Ftest.rb?ref=main')
) {
return replyJSON(200, {
content: Buffer.from(`old content`).toString('base64'),
})
} else if (route('PUT', 'repos/OWNER/REPO/contents/formula%2Ftest.rb')) {
const payload = JSON.parse(options.body || '')
t.is('main', 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' },
})
}
throw `not stubbed: ${options.method} ${url}`
}

const url = await editGithubBlob({
apiClient: api('ATOKEN', { fetch: stubbedFetch, logRequests: false }),
owner: 'OWNER',
repo: 'REPO',
filePath: 'formula/test.rb',
replace: (oldContent) => oldContent.toUpperCase(),
})
t.is('https://github.com/OWNER/REPO/commit/NEWSHA', url)
})

test('edit-github-blob via pull request', 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/OWNER/REPO/forks')) {
return replyJSON(200, {})
} else if (route('GET', 'user')) {
return replyJSON(200, { login: 'FORKOWNER' })
} 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',
filePath: 'formula/test.rb',
replace: (oldContent) => oldContent.toUpperCase(),
})
t.is('https://github.com/OWNER/REPO/pull/123', url)
})
17 changes: 13 additions & 4 deletions src/edit-github-blob.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { API } from './api'
import { RequestError } from '@octokit/request-error'
import { basename } from 'path'

async function retry<T>(
Expand Down Expand Up @@ -67,10 +68,18 @@ export default async function (params: Options): Promise<string> {
const timestamp = Math.round(Date.now() / 1000)
headBranch = `update-${basename(filePath)}-${timestamp}`
if (needsFork) {
await api.repos.mergeUpstream({
...headRepo,
branch: repoRes.data.default_branch,
})
try {
await api.repos.mergeUpstream({
...headRepo,
branch: repoRes.data.default_branch,
})
} catch (err) {
if (err instanceof RequestError && err.status === 409) {
// ignore
} else {
throw err
}
}
}
await retry(needsFork ? 6 : 0, 5000, async () => {
await api.git.createRef({
Expand Down
2 changes: 1 addition & 1 deletion src/main-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ test('prepareEdit()', async (t) => {
}
throw url
}
const apiClient = api('ATOKEN', { fetch: stubbedFetch })
const apiClient = api('ATOKEN', { fetch: stubbedFetch, logRequests: false })

const opts = await prepareEdit(ctx, apiClient, apiClient)
t.is(opts.owner, 'Homebrew')
Expand Down

0 comments on commit c901481

Please sign in to comment.