From d2e6543d2b7a72b8adbcc3d69d5f666489f60717 Mon Sep 17 00:00:00 2001 From: Dom Harrington Date: Thu, 24 Aug 2023 14:41:01 +0100 Subject: [PATCH] feat(bitbucket): add support for constructing `pull_request` payloads (#23) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 🧰 Changes Add support for constructing `pull_request` payloads TODO - [x] Update action code samples on the README ## 🧬 QA & Testing Do the tests pass? More thorough instructions incoming! --- README.md | 22 +++++--- __tests__/lib/context.test.js | 56 ++++++++++++++++---- lib/context.js | 99 +++++++++++++++++++++++------------ 3 files changed, 127 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 06d3d1d..35e9ce7 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ on: push: branches: - main + pull_request: + types: [opened, synchronize] jobs: sync: runs-on: ubuntu-latest @@ -40,14 +42,20 @@ npx @readme/micro@v2.4.0 './*{yaml,yml,json}' --key=$README_MICRO_SECRET ### As a Bitbucket Pipeline ```yaml -image: node:18 - +definitions: + steps: + - step: &readme-micro + name: ReadMe Micro + image: node:18 + script: + - npx @readme/micro@v2.4.0 '**/*.{yaml,yml,json}' --key=$README_MICRO_SECRET + +# Run Pipeline to sync OpenAPI files for every push to the `main` branch pipelines: branches: - # Run Pipeline to sync OpenAPI files for every push to the `main` branch main: - - step: - name: ReadMe Micro - script: - - npx @readme/micro@v2.4.0 './*{yaml,yml,json}' --key=$README_MICRO_SECRET + - step: *readme-micro + pull-requests: + '**': + - step: *readme-micro ``` diff --git a/__tests__/lib/context.test.js b/__tests__/lib/context.test.js index 03757d9..000c660 100644 --- a/__tests__/lib/context.test.js +++ b/__tests__/lib/context.test.js @@ -91,9 +91,9 @@ describe('getContext()', () => { .reply(200, { display_name: 'Dom H' }); await expect(getContext()).resolves.toMatchObject({ + eventName: 'push', ref: `refs/heads/${process.env.BITBUCKET_BRANCH}`, sha: process.env.BITBUCKET_COMMIT, - actor: 'Dom H', runId: parseInt(process.env.BITBUCKET_BUILD_NUMBER, 10), payload: { commits: [ @@ -109,6 +109,9 @@ describe('getContext()', () => { organization: process.env.BITBUCKET_WORKSPACE, name: process.env.BITBUCKET_REPO_SLUG, }, + organization: { + login: process.env.BITBUCKET_WORKSPACE, + }, }, }); @@ -151,18 +154,53 @@ describe('getContext()', () => { }); await expect(getContext()).resolves.toMatchObject({ - actor: 'Unknown User', payload: { - // commits: [ - // { - // author: { - // username: 'Unknown User', - // }, - // }, - // ], + commits: [ + { + author: { + name: 'Unknown User', + }, + }, + ], }, }); mock.done(); }); + + it('should work for `pull_requests`', async () => { + process.env.BITBUCKET_COMMIT = latestCommitSha; + process.env.BITBUCKET_STEP_TRIGGERER_UUID = '{636fcf11-a096-4b88-99ed-ce185e001fdb}'; + process.env.BITBUCKET_BUILD_NUMBER = '1234'; + process.env.BITBUCKET_WORKSPACE = 'workspace-name'; + process.env.BITBUCKET_REPO_SLUG = 'repo-name'; + process.env.BITBUCKET_BRANCH = 'main'; + + process.env.BITBUCKET_PR_ID = '999'; + + // eslint-disable-next-line global-require + const getContext = require('../../lib/context'); + + const mock = nock('https://api.bitbucket.org') + .get(`/2.0/users/${encodeURIComponent(process.env.BITBUCKET_STEP_TRIGGERER_UUID)}`) + .reply(200, { display_name: 'Dom H' }); + + await expect(getContext()).resolves.toMatchObject({ + eventName: 'pull_request', + ref: `refs/heads/${process.env.BITBUCKET_BRANCH}`, + sha: process.env.BITBUCKET_COMMIT, + runId: parseInt(process.env.BITBUCKET_BUILD_NUMBER, 10), + payload: { + number: process.env.BITBUCKET_PR_ID, + repository: { + name: process.env.BITBUCKET_REPO_SLUG, + }, + organization: { + login: process.env.BITBUCKET_WORKSPACE, + }, + }, + }); + + mock.done(); + }); }); }); diff --git a/lib/context.js b/lib/context.js index 798c8de..ee62fbd 100644 --- a/lib/context.js +++ b/lib/context.js @@ -37,6 +37,14 @@ module.exports = async function getContext() { case 'GitHub Actions': return context; case 'Bitbucket Pipelines': { + const baseContext = { + ref: process.env.BITBUCKET_TAG + ? `refs/tags/${process.env.BITBUCKET_TAG}` + : `refs/heads/${process.env.BITBUCKET_BRANCH}`, + sha: process.env.BITBUCKET_COMMIT, + runId: parseInt(process.env.BITBUCKET_BUILD_NUMBER, 10), + }; + // Pipelines dont give us the username of the user who made the action // happen, so we have to make an extra request to fetch this // https://jira.atlassian.com/browse/BCLOUD-16711 @@ -52,42 +60,65 @@ module.exports = async function getContext() { const actor = response.data.display_name || 'Unknown User'; - return { - ref: process.env.BITBUCKET_TAG - ? `refs/tags/${process.env.BITBUCKET_TAG}` - : `refs/heads/${process.env.BITBUCKET_BRANCH}`, - sha: process.env.BITBUCKET_COMMIT, - actor, - runId: parseInt(process.env.BITBUCKET_BUILD_NUMBER, 10), - payload: { - repository: { - name: process.env.BITBUCKET_REPO_SLUG, - organization: process.env.BITBUCKET_WORKSPACE, - }, - commits: [ - { - message: execSync('git log --format=%B -n 1 $BITBUCKET_COMMIT', { - env: { BITBUCKET_COMMIT: process.env.BITBUCKET_COMMIT }, - encoding: 'utf-8', - }).trim(), - // Get the unix timestamp of the commit then convert it to - // an ISO8601 UTC string - // - // https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emctem - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString - timestamp: new Date( - execSync('git show -s --format=%ct $BITBUCKET_COMMIT', { - env: { BITBUCKET_COMMIT: process.env.BITBUCKET_COMMIT }, - encoding: 'utf-8', - }).trim() * 1000 - ).toISOString(), - author: { - name: actor, + // BITBUCKET_PR_ID only set on pull request triggered builds + // this is how we determine if it's a `push` or `pull_request` + const eventName = process.env.BITBUCKET_PR_ID ? 'pull_request' : 'push'; + + switch (eventName) { + case 'push': + return { + ...baseContext, + eventName, + payload: { + repository: { + name: process.env.BITBUCKET_REPO_SLUG, + // TODO we should remove this in a future release + organization: process.env.BITBUCKET_WORKSPACE, + }, + organization: { + login: process.env.BITBUCKET_WORKSPACE, }, + commits: [ + { + message: execSync('git log --format=%B -n 1 $BITBUCKET_COMMIT', { + env: { BITBUCKET_COMMIT: process.env.BITBUCKET_COMMIT }, + encoding: 'utf-8', + }).trim(), + // Get the unix timestamp of the commit then convert it to + // an ISO8601 UTC string + // + // https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emctem + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString + timestamp: new Date( + execSync('git show -s --format=%ct $BITBUCKET_COMMIT', { + env: { BITBUCKET_COMMIT: process.env.BITBUCKET_COMMIT }, + encoding: 'utf-8', + }).trim() * 1000 + ).toISOString(), + author: { + name: actor, + }, + }, + ], }, - ], - }, - }; + }; + case 'pull_request': + return { + ...baseContext, + eventName, + payload: { + number: process.env.BITBUCKET_PR_ID, + repository: { + name: process.env.BITBUCKET_REPO_SLUG, + }, + organization: { + login: process.env.BITBUCKET_WORKSPACE, + }, + }, + }; + default: + return {}; + } } default: return {};