├── .github └── CODEOWNERS ├── .gitignore ├── .vscode └── settings.json ├── CHANGELOG.md ├── README.md ├── app.yml ├── get-changed-packages.ts ├── index.test.js ├── index.ts ├── next-env.d.ts ├── package.json ├── pages └── api │ └── webhook.ts ├── test └── fixtures │ ├── pull_request.opened.json │ ├── pull_request.synchronize.json │ └── release_pull_request.opened.json ├── tsconfig.json └── yarn.lock /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @emmatown 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @changesets/bot 2 | 3 | ## 1.2.0 4 | 5 | ### Minor Changes 6 | 7 | - Add a link to create a changeset from the comment 8 | - Optimise network calls 9 | 10 | ## 1.1.5 11 | 12 | ### Patch Changes 13 | 14 | - 6dbc7dc: Fix babel configs for building packages to produce working dists for node scripts. 15 | 16 | ## 1.1.4 17 | 18 | ### Patch Changes 19 | 20 | - 88dd1b5: Refactored bot to combine endpoints and added unit tests 21 | 22 | ## 1.1.3 23 | 24 | ### Patch Changes 25 | 26 | - 5e9ecdc: Fix spelling error 27 | - 2ca59c0: Change deployment environment to staging 28 | 29 | ## 1.1.2 30 | 31 | ### Patch Changes 32 | 33 | - a18dd18: Got feedback that our changeset messages could be a bit loud/scary. Here is some lighter, friendlier text 34 | 35 | ## 1.1.1 36 | 37 | - [patch] fa74183: 38 | 39 | - Link messages out to information on changesets 40 | 41 | - [patch] a1d1b56: 42 | 43 | - Display commit sha instead of commit message in bot comment 44 | 45 | ## 1.1.0 46 | 47 | - [patch] f7a6395: 48 | 49 | - Handle case where committer field in webhook event is null 50 | 51 | - [minor] 9bd107d: 52 | 53 | - Added new bot to detect changesets on PRs 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # changeset-bot 2 | 3 | > A GitHub App built with [Probot](https://github.com/probot/probot) to detect [changesets](https://github.com/atlassian/changesets) in PRs 4 | 5 | ## Install the bot at https://github.com/apps/changeset-bot 6 | 7 | 8 | 9 | This bot will comment on PRs saying that either a user might need to add a changeset(note that PRs changing things like documentation generally don't need a changeset)or say that the PR is good and already has a changeset. 10 | 11 | screenshot of changeset bot message from https://github.com/mitchellhamilton/manypkg/pull/18 before a changeset was added 12 | 13 | screenshot of the changeset bot message from https://github.com/mitchellhamilton/manypkg/pull/18 showing the changeset good to go message 14 | 15 | 16 | Sometimes, a contributor won't add a changeset to a PR but you might want to merge in the PR without having to wait on them to add it. To address this, this bot adds a link with the filename pre-filled to add a changeset so all you have to do is write the changeset and click commit. 17 | 18 | screenshot of the changeset bot message from https://github.com/mitchellhamilton/manypkg/pull/18 focused on the create a changeset link 19 | 20 | screenshot of creating a changeset directly on GitHub 21 | 22 | screenshot of the GitHub file creation page focusing on the commit button 23 | 24 | screenshot of the changeset bot message from https://github.com/mitchellhamilton/manypkg/pull/18 showing the changeset good to go message 25 | 26 | When writing the changeset, it should look something like this with the packages that are being released in the YAML front matter with associated semver bump types and the summary of the changes in markdown. 27 | 28 | ```markdown 29 | --- 30 | '@changesets/cli': major 31 | '@changesets/read': minor 32 | --- 33 | 34 | A very helpful description of the changes 35 | ``` 36 | --- 37 | 38 | The information below is for contributing to the bot. 39 | 40 | 41 | ## Setup 42 | 43 | ```sh 44 | yarn 45 | ``` 46 | 47 | ## Behaviour 48 | 49 | The changeset bot will listen for pull requests being opened and pull requests that have been updated, upon which it will 50 | then scan through the files for a changeset that has been added. The bot will make a comment on the PR stating 51 | whether it found a changeset or not, as well as the message of the latest commit. If the PR is being updated 52 | then the bot will update the existing comment 53 | -------------------------------------------------------------------------------- /app.yml: -------------------------------------------------------------------------------- 1 | # This is a GitHub App Manifest. These settings will be used by default when 2 | # initially configuring your GitHub App. 3 | # 4 | # NOTE: changing this file will not update your GitHub App settings. 5 | # You must visit github.com/settings/apps/your-app-name to edit them. 6 | # 7 | # Read more about configuring your GitHub App: 8 | # https://probot.github.io/docs/development/#configuring-a-github-app 9 | # 10 | # Read more about GitHub App Manifests: 11 | # https://developer.github.com/apps/building-github-apps/creating-github-apps-from-a-manifest/ 12 | 13 | # The list of events the GitHub App subscribes to. 14 | # Uncomment the event names below to enable them. 15 | default_events: 16 | # - check_run 17 | # - check_suite 18 | # - commit_comment 19 | # - create 20 | # - delete 21 | # - deployment 22 | # - deployment_status 23 | # - fork 24 | # - gollum 25 | # - issue_comment 26 | - issues 27 | # - label 28 | # - milestone 29 | # - member 30 | # - membership 31 | # - org_block 32 | # - organization 33 | # - page_build 34 | # - project 35 | # - project_card 36 | # - project_column 37 | # - public 38 | - pull_request 39 | # - pull_request_review 40 | # - pull_request_review_comment 41 | # - push 42 | # - release 43 | # - repository 44 | # - repository_import 45 | # - status 46 | # - team 47 | # - team_add 48 | # - watch 49 | 50 | # The set of permissions needed by the GitHub App. The format of the object uses 51 | # the permission name for the key (for example, issues) and the access type for 52 | # the value (for example, write). 53 | # Valid values are `read`, `write`, and `none` 54 | default_permissions: 55 | # Repository creation, deletion, settings, teams, and collaborators. 56 | # https://developer.github.com/v3/apps/permissions/#permission-on-administration 57 | # administration: read 58 | 59 | # Checks on code. 60 | # https://developer.github.com/v3/apps/permissions/#permission-on-checks 61 | # checks: read 62 | 63 | # Repository contents, commits, branches, downloads, releases, and merges. 64 | # https://developer.github.com/v3/apps/permissions/#permission-on-contents 65 | # contents: read 66 | 67 | # Deployments and deployment statuses. 68 | # https://developer.github.com/v3/apps/permissions/#permission-on-deployments 69 | # deployments: read 70 | 71 | # Issues and related comments, assignees, labels, and milestones. 72 | # https://developer.github.com/v3/apps/permissions/#permission-on-issues 73 | issues: write 74 | 75 | # Search repositories, list collaborators, and access repository metadata. 76 | # https://developer.github.com/v3/apps/permissions/#metadata-permissions 77 | metadata: read 78 | 79 | # Retrieve Pages statuses, configuration, and builds, as well as create new builds. 80 | # https://developer.github.com/v3/apps/permissions/#permission-on-pages 81 | # pages: read 82 | 83 | # Pull requests and related comments, assignees, labels, milestones, and merges. 84 | # https://developer.github.com/v3/apps/permissions/#permission-on-pull-requests 85 | pull_requests: write 86 | 87 | # Manage the post-receive hooks for a repository. 88 | # https://developer.github.com/v3/apps/permissions/#permission-on-repository-hooks 89 | # repository_hooks: read 90 | 91 | # Manage repository projects, columns, and cards. 92 | # https://developer.github.com/v3/apps/permissions/#permission-on-repository-projects 93 | # repository_projects: read 94 | 95 | # Retrieve security vulnerability alerts. 96 | # https://developer.github.com/v4/object/repositoryvulnerabilityalert/ 97 | # vulnerability_alerts: read 98 | 99 | # Commit statuses. 100 | # https://developer.github.com/v3/apps/permissions/#permission-on-statuses 101 | # statuses: read 102 | 103 | # Organization members and teams. 104 | # https://developer.github.com/v3/apps/permissions/#permission-on-members 105 | # members: read 106 | 107 | # View and manage users blocked by the organization. 108 | # https://developer.github.com/v3/apps/permissions/#permission-on-organization-user-blocking 109 | # organization_user_blocking: read 110 | 111 | # Manage organization projects, columns, and cards. 112 | # https://developer.github.com/v3/apps/permissions/#permission-on-organization-projects 113 | # organization_projects: read 114 | 115 | # Manage team discussions and related comments. 116 | # https://developer.github.com/v3/apps/permissions/#permission-on-team-discussions 117 | # team_discussions: read 118 | 119 | # Manage the post-receive hooks for an organization. 120 | # https://developer.github.com/v3/apps/permissions/#permission-on-organization-hooks 121 | # organization_hooks: read 122 | 123 | # Get notified of, and update, content references. 124 | # https://developer.github.com/v3/apps/permissions/ 125 | # organization_administration: read 126 | 127 | 128 | # The name of the GitHub App. Defaults to the name specified in package.json 129 | # name: My Probot App 130 | 131 | # The homepage of your GitHub App. 132 | # url: https://example.com/ 133 | 134 | # A description of the GitHub App. 135 | # description: A description of my awesome app 136 | 137 | # Set to true when your GitHub App is available to the public or false when it is only accessible to the owner of the app. 138 | # Default: true 139 | # public: false 140 | -------------------------------------------------------------------------------- /get-changed-packages.ts: -------------------------------------------------------------------------------- 1 | import nodePath from "path"; 2 | import micromatch from "micromatch"; 3 | import { ProbotOctokit } from "probot"; 4 | import fetch from "node-fetch"; 5 | import { safeLoad } from "js-yaml"; 6 | import { Packages, Tool } from "@manypkg/get-packages"; 7 | import assembleReleasePlan from "@changesets/assemble-release-plan"; 8 | import { parse as parseConfig } from "@changesets/config"; 9 | import { PreState, NewChangeset } from "@changesets/types"; 10 | import parseChangeset from "@changesets/parse"; 11 | 12 | export let getChangedPackages = async ({ 13 | owner, 14 | repo, 15 | ref, 16 | changedFiles: changedFilesPromise, 17 | octokit, 18 | installationToken, 19 | }: { 20 | owner: string; 21 | repo: string; 22 | ref: string; 23 | changedFiles: string[] | Promise; 24 | octokit: InstanceType; 25 | installationToken: string; 26 | }) => { 27 | let hasErrored = false; 28 | let encodedCredentials = Buffer.from( 29 | `x-access-token:${installationToken}` 30 | ).toString("base64"); 31 | 32 | function fetchFile(path: string) { 33 | return fetch( 34 | `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${path}`, 35 | { 36 | headers: { 37 | Authorization: `Basic ${encodedCredentials}`, 38 | }, 39 | } 40 | ); 41 | } 42 | 43 | function fetchJsonFile(path: string) { 44 | return fetchFile(path) 45 | .then((x) => x.json()) 46 | .catch((err) => { 47 | hasErrored = true; 48 | console.error(err); 49 | return {}; 50 | }); 51 | } 52 | 53 | function fetchTextFile(path: string) { 54 | return fetchFile(path) 55 | .then((x) => x.text()) 56 | .catch((err) => { 57 | hasErrored = true; 58 | console.error(err); 59 | return ""; 60 | }); 61 | } 62 | 63 | async function getPackage(pkgPath: string) { 64 | let jsonContent = await fetchJsonFile(pkgPath + "/package.json"); 65 | return { 66 | packageJson: jsonContent, 67 | dir: pkgPath, 68 | }; 69 | } 70 | 71 | let rootPackageJsonContentsPromise = fetchJsonFile("package.json"); 72 | let configPromise: Promise = fetchJsonFile(".changeset/config.json"); 73 | 74 | let tree = await octokit.git.getTree({ 75 | owner, 76 | repo, 77 | recursive: "1", 78 | tree_sha: ref, 79 | }); 80 | 81 | let preStatePromise: Promise | undefined; 82 | let changesetPromises: Promise[] = []; 83 | let potentialWorkspaceDirectories: string[] = []; 84 | let isPnpm = false; 85 | let changedFiles = await changedFilesPromise; 86 | 87 | for (let item of tree.data.tree) { 88 | if (!item.path) continue; 89 | if (item.path.endsWith("/package.json")) { 90 | let dirPath = nodePath.dirname(item.path); 91 | potentialWorkspaceDirectories.push(dirPath); 92 | } else if (item.path === "pnpm-workspace.yaml") { 93 | isPnpm = true; 94 | } else if (item.path === ".changeset/pre.json") { 95 | preStatePromise = fetchJsonFile(".changeset/pre.json"); 96 | } else if ( 97 | item.path !== ".changeset/README.md" && 98 | item.path.startsWith(".changeset") && 99 | item.path.endsWith(".md") && 100 | changedFiles.includes(item.path) 101 | ) { 102 | let res = /\.changeset\/([^\.]+)\.md/.exec(item.path); 103 | if (!res) { 104 | throw new Error("could not get name from changeset filename"); 105 | } 106 | let id = res[1]; 107 | changesetPromises.push( 108 | fetchTextFile(item.path).then((text) => { 109 | return { ...parseChangeset(text), id }; 110 | }) 111 | ); 112 | } 113 | } 114 | let tool: 115 | | { 116 | tool: Tool; 117 | globs: string[]; 118 | } 119 | | undefined; 120 | 121 | if (isPnpm) { 122 | tool = { 123 | tool: "pnpm", 124 | globs: safeLoad(await fetchTextFile("pnpm-workspace.yaml")).packages, 125 | }; 126 | } else { 127 | let rootPackageJsonContent = await rootPackageJsonContentsPromise; 128 | 129 | if (rootPackageJsonContent.workspaces) { 130 | if (!Array.isArray(rootPackageJsonContent.workspaces)) { 131 | tool = { 132 | tool: "yarn", 133 | globs: rootPackageJsonContent.workspaces.packages, 134 | }; 135 | } else { 136 | tool = { 137 | tool: "yarn", 138 | globs: rootPackageJsonContent.workspaces, 139 | }; 140 | } 141 | } else if ( 142 | rootPackageJsonContent.bolt && 143 | rootPackageJsonContent.bolt.workspaces 144 | ) { 145 | tool = { 146 | tool: "bolt", 147 | globs: rootPackageJsonContent.bolt.workspaces, 148 | }; 149 | } 150 | } 151 | 152 | let rootPackageJsonContent = await rootPackageJsonContentsPromise; 153 | 154 | let packages: Packages = { 155 | root: { 156 | dir: "/", 157 | packageJson: rootPackageJsonContent, 158 | }, 159 | tool: tool ? tool.tool : "root", 160 | packages: [], 161 | }; 162 | 163 | if (tool) { 164 | if ( 165 | !Array.isArray(tool.globs) || 166 | !tool.globs.every((x) => typeof x === "string") 167 | ) { 168 | throw new Error("globs are not valid: " + JSON.stringify(tool.globs)); 169 | } 170 | let matches = micromatch(potentialWorkspaceDirectories, tool.globs); 171 | 172 | packages.packages = await Promise.all( 173 | matches.map((dir) => getPackage(dir)) 174 | ); 175 | } else { 176 | packages.packages.push(packages.root); 177 | } 178 | if (hasErrored) { 179 | throw new Error("an error occurred when fetching files"); 180 | } 181 | 182 | const releasePlan = assembleReleasePlan( 183 | await Promise.all(changesetPromises), 184 | packages, 185 | await configPromise.then((rawConfig) => parseConfig(rawConfig, packages)), 186 | await preStatePromise 187 | ); 188 | 189 | return { 190 | changedPackages: (packages.tool === "root" 191 | ? packages.packages 192 | : packages.packages.filter((pkg) => 193 | changedFiles.some((changedFile) => changedFile.startsWith(`${pkg.dir}/`)) 194 | ) 195 | ).map((x) => x.packageJson.name), 196 | releasePlan, 197 | }; 198 | }; 199 | -------------------------------------------------------------------------------- /index.test.js: -------------------------------------------------------------------------------- 1 | const nock = require("nock"); 2 | const { Probot } = require("probot"); 3 | const outdent = require("outdent"); 4 | 5 | const changesetBot = require("."); 6 | 7 | const pullRequestOpen = require("./test/fixtures/pull_request.opened"); 8 | const pullRequestSynchronize = require("./test/fixtures/pull_request.synchronize"); 9 | const releasePullRequestOpen = require("./test/fixtures/release_pull_request.opened"); 10 | 11 | nock.disableNetConnect(); 12 | 13 | /* 14 | Oh god none of these tests work - we should really do something about having this tested 15 | */ 16 | describe.skip("changeset-bot", () => { 17 | let probot; 18 | 19 | beforeEach(() => { 20 | probot = new Probot({}); 21 | const app = probot.load(changesetBot); 22 | 23 | // just return a test token 24 | app.app = () => "test.ts"; 25 | }); 26 | 27 | it("should add a comment when there is no comment", async () => { 28 | nock("https://api.github.com") 29 | .get("/repos/pyu/testing-things/issues/1/comments") 30 | .reply(200, []); 31 | 32 | nock("https://api.github.com") 33 | .get("/repos/pyu/testing-things/pulls/1/files") 34 | .reply(200, [ 35 | { filename: ".changeset/something/changes.md", status: "added" } 36 | ]); 37 | 38 | nock("https://api.github.com") 39 | .get("/repos/pyu/testing-things/pulls/1/commits") 40 | .reply(200, [{ sha: "ABCDE" }]); 41 | 42 | nock("https://api.github.com") 43 | .post("/repos/pyu/testing-things/issues/1/comments", body => { 44 | expect(body.comment_id).toBeNull(); 45 | return true; 46 | }) 47 | .reply(200); 48 | 49 | await probot.receive({ 50 | name: "pull_request", 51 | payload: pullRequestOpen 52 | }); 53 | }); 54 | 55 | it("should update a comment when there is a comment", async () => { 56 | nock("https://api.github.com") 57 | .get("/repos/pyu/testing-things/issues/1/comments") 58 | .reply(200, [ 59 | { 60 | id: 7, 61 | user: { 62 | login: "changeset-bot[bot]" 63 | } 64 | } 65 | ]); 66 | 67 | nock("https://api.github.com") 68 | .get("/repos/pyu/testing-things/pulls/1/files") 69 | .reply(200, [ 70 | { filename: ".changeset/something/changes.md", status: "added" } 71 | ]); 72 | 73 | nock("https://api.github.com") 74 | .get("/repos/pyu/testing-things/pulls/1/commits") 75 | .reply(200, [{ sha: "ABCDE" }]); 76 | 77 | nock("https://api.github.com") 78 | .patch("/repos/pyu/testing-things/issues/comments/7", body => { 79 | expect(body.number).toBe(1); 80 | return true; 81 | }) 82 | .reply(200); 83 | 84 | await probot.receive({ 85 | name: "pull_request", 86 | payload: pullRequestSynchronize 87 | }); 88 | }); 89 | 90 | it("should show correct message if there is a changeset", async () => { 91 | nock("https://api.github.com") 92 | .get("/repos/pyu/testing-things/issues/1/comments") 93 | .reply(200, []); 94 | 95 | nock("https://api.github.com") 96 | .get("/repos/pyu/testing-things/pulls/1/files") 97 | .reply(200, [ 98 | { filename: ".changeset/something/changes.md", status: "added" } 99 | ]); 100 | 101 | nock("https://api.github.com") 102 | .get("/repos/pyu/testing-things/pulls/1/commits") 103 | .reply(200, [{ sha: "ABCDE" }]); 104 | 105 | nock("https://api.github.com") 106 | .post("/repos/pyu/testing-things/issues/1/comments", ({ body }) => { 107 | expect(body).toEqual(outdent` 108 | ### 🦋 Changeset is good to go 109 | 110 | Latest commit: ABCDE 111 | 112 | **We got this.** 113 | 114 | Not sure what this means? [Click here to learn what changesets are](https://github.com/Noviny/changesets/blob/master/docs/adding-a-changeset.md).`); 115 | return true; 116 | }) 117 | .reply(200); 118 | 119 | await probot.receive({ 120 | name: "pull_request", 121 | payload: pullRequestOpen 122 | }); 123 | }); 124 | 125 | it("should show correct message if there is no changeset", async () => { 126 | nock("https://api.github.com") 127 | .get("/repos/pyu/testing-things/issues/1/comments") 128 | .reply(200, []); 129 | 130 | nock("https://api.github.com") 131 | .get("/repos/pyu/testing-things/pulls/1/files") 132 | .reply(200, [{ filename: "index.js", status: "added" }]); 133 | 134 | nock("https://api.github.com") 135 | .get("/repos/pyu/testing-things/pulls/1/commits") 136 | .reply(200, [{ sha: "ABCDE" }]); 137 | 138 | nock("https://api.github.com") 139 | .post("/repos/pyu/testing-things/issues/1/comments", ({ body }) => { 140 | expect(body).toEqual(outdent` 141 | ### 💥 No Changeset 142 | 143 | Latest commit: ABCDE 144 | 145 | Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂 146 | 147 | **If these changes should be published to npm, you need to add a changeset.** 148 | 149 | [Click here to learn what changesets are, and how to add one](https://github.com/Noviny/changesets/blob/master/docs/adding-a-changeset.md).`); 150 | return true; 151 | }) 152 | .reply(200); 153 | 154 | await probot.receive({ 155 | name: "pull_request", 156 | payload: pullRequestOpen 157 | }); 158 | }); 159 | 160 | it("shouldn't add a comment to a release pull request", async () => { 161 | nock("https://api.github.com").reply(() => { 162 | // shouldn't reach this, but if it does - let it fail 163 | expect(true).toBe(false); 164 | }); 165 | 166 | await probot.receive({ 167 | name: "pull_request", 168 | payload: releasePullRequestOpen 169 | }); 170 | }); 171 | }); 172 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import humanId from "human-id"; 3 | import { Probot, Context } from "probot"; 4 | import { EmitterWebhookEvent } from "@octokit/webhooks"; 5 | import { getChangedPackages } from "./get-changed-packages"; 6 | import { 7 | ReleasePlan, 8 | ComprehensiveRelease, 9 | VersionType, 10 | } from "@changesets/types"; 11 | import markdownTable from "markdown-table"; 12 | import { captureException } from "@sentry/node"; 13 | import { ValidationError } from "@changesets/errors"; 14 | 15 | const getReleasePlanMessage = (releasePlan: ReleasePlan | null) => { 16 | if (!releasePlan) return ""; 17 | 18 | const publishableReleases = releasePlan.releases.filter( 19 | (x): x is ComprehensiveRelease & { type: Exclude } => 20 | x.type !== "none" 21 | ); 22 | 23 | let table = markdownTable([ 24 | ["Name", "Type"], 25 | ...publishableReleases.map((x) => { 26 | return [ 27 | x.name, 28 | { 29 | major: "Major", 30 | minor: "Minor", 31 | patch: "Patch", 32 | }[x.type], 33 | ]; 34 | }), 35 | ]); 36 | 37 | return `
This PR includes ${ 38 | releasePlan.changesets.length 39 | ? `changesets to release ${ 40 | publishableReleases.length === 1 41 | ? "1 package" 42 | : `${publishableReleases.length} packages` 43 | }` 44 | : "no changesets" 45 | } 46 | 47 | ${ 48 | publishableReleases.length 49 | ? table 50 | : "When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types" 51 | } 52 | 53 |
`; 54 | }; 55 | 56 | const getAbsentMessage = ( 57 | commitSha: string, 58 | addChangesetUrl: string, 59 | releasePlan: ReleasePlan | null 60 | ) => `### ⚠️ No Changeset found 61 | 62 | Latest commit: ${commitSha} 63 | 64 | Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.** 65 | 66 | ${getReleasePlanMessage(releasePlan)} 67 | 68 | [Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md). 69 | 70 | [Click here if you're a maintainer who wants to add a changeset to this PR](${addChangesetUrl}) 71 | 72 | `; 73 | 74 | const getApproveMessage = ( 75 | commitSha: string, 76 | addChangesetUrl: string, 77 | releasePlan: ReleasePlan | null 78 | ) => `### 🦋 Changeset detected 79 | 80 | Latest commit: ${commitSha} 81 | 82 | **The changes in this PR will be included in the next version bump.** 83 | 84 | ${getReleasePlanMessage(releasePlan)} 85 | 86 | Not sure what this means? [Click here to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md). 87 | 88 | [Click here if you're a maintainer who wants to add another changeset to this PR](${addChangesetUrl}) 89 | 90 | `; 91 | 92 | const getNewChangesetTemplate = (changedPackages: string[], title: string) => 93 | encodeURIComponent(`--- 94 | ${changedPackages.map((x) => `"${x}": patch`).join("\n")} 95 | --- 96 | 97 | ${title} 98 | `); 99 | 100 | type PRContext = EmitterWebhookEvent< 101 | "pull_request.opened" | "pull_request.synchronize" 102 | > & 103 | Omit; 104 | 105 | const getCommentId = ( 106 | context: PRContext, 107 | params: { repo: string; owner: string; issue_number: number } 108 | ) => 109 | context.octokit.issues.listComments(params).then((comments) => { 110 | const changesetBotComment = comments.data.find( 111 | // TODO: find what the current user is in some way or something 112 | (comment) => 113 | comment.user?.login === "changeset-bot[bot]" || 114 | comment.user?.login === "changesets-test-bot[bot]" 115 | ); 116 | return changesetBotComment ? changesetBotComment.id : null; 117 | }); 118 | 119 | const hasChangesetBeenAdded = ( 120 | changedFilesPromise: ReturnType 121 | ) => 122 | changedFilesPromise.then((files) => 123 | files.data.some( 124 | (file) => 125 | file.status === "added" && 126 | /^\.changeset\/.+\.md$/.test(file.filename) && 127 | file.filename !== ".changeset/README.md" 128 | ) 129 | ); 130 | 131 | export default (app: Probot) => { 132 | app.auth(); 133 | app.log("Yay, the app was loaded!"); 134 | 135 | app.on( 136 | ["pull_request.opened", "pull_request.synchronize"], 137 | async (context) => { 138 | if ( 139 | context.payload.pull_request.head.ref.startsWith("changeset-release") 140 | ) { 141 | return; 142 | } 143 | 144 | let errFromFetchingChangedFiles = ""; 145 | 146 | try { 147 | let number = context.payload.number; 148 | 149 | let repo = { 150 | repo: context.payload.repository.name, 151 | owner: context.payload.repository.owner.login, 152 | }; 153 | 154 | const latestCommitSha = context.payload.pull_request.head.sha; 155 | let changedFilesPromise = context.octokit.pulls.listFiles({ 156 | ...repo, 157 | pull_number: number, 158 | }); 159 | 160 | const [commentId, hasChangeset, { changedPackages, releasePlan }] = 161 | await Promise.all([ 162 | // we know the comment won't exist on opened events 163 | // ok, well like technically that's wrong 164 | // but reducing time is nice here so that 165 | // deploying this doesn't cost money 166 | context.payload.action === "synchronize" 167 | ? getCommentId(context, { ...repo, issue_number: number }) 168 | : undefined, 169 | hasChangesetBeenAdded(changedFilesPromise), 170 | getChangedPackages({ 171 | repo: context.payload.pull_request.head.repo.name, 172 | owner: context.payload.pull_request.head.repo.owner.login, 173 | ref: context.payload.pull_request.head.ref, 174 | changedFiles: changedFilesPromise.then((x) => 175 | x.data.map((x) => x.filename) 176 | ), 177 | octokit: context.octokit, 178 | installationToken: ( 179 | await ( 180 | await app.auth() 181 | ).apps.createInstallationAccessToken({ 182 | installation_id: context.payload.installation!.id, 183 | }) 184 | ).data.token, 185 | }).catch((err) => { 186 | if (err instanceof ValidationError) { 187 | errFromFetchingChangedFiles = `
💥 An error occurred when fetching the changed packages and changesets in this PR\n\n\`\`\`\n${err.message}\n\`\`\`\n\n
\n`; 188 | } else { 189 | console.error(err); 190 | captureException(err); 191 | } 192 | return { 193 | changedPackages: ["@fake-scope/fake-pkg"], 194 | releasePlan: null, 195 | }; 196 | }), 197 | ] as const); 198 | 199 | let addChangesetUrl = `${ 200 | context.payload.pull_request.head.repo.html_url 201 | }/new/${ 202 | context.payload.pull_request.head.ref 203 | }?filename=.changeset/${humanId({ 204 | separator: "-", 205 | capitalize: false, 206 | })}.md&value=${getNewChangesetTemplate( 207 | changedPackages, 208 | context.payload.pull_request.title 209 | )}`; 210 | 211 | let prComment = { 212 | ...repo, 213 | issue_number: number, 214 | body: 215 | (hasChangeset 216 | ? getApproveMessage(latestCommitSha, addChangesetUrl, releasePlan) 217 | : getAbsentMessage( 218 | latestCommitSha, 219 | addChangesetUrl, 220 | releasePlan 221 | )) + errFromFetchingChangedFiles, 222 | }; 223 | 224 | if (commentId != null) { 225 | return context.octokit.issues.updateComment({ 226 | ...prComment, 227 | comment_id: commentId, 228 | }); 229 | } 230 | return context.octokit.issues.createComment(prComment); 231 | } catch (err) { 232 | console.error(err); 233 | throw err; 234 | } 235 | } 236 | ); 237 | }; 238 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@changesets/bot", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "private": true, 6 | "repository": "https://github.com/changesets/bot", 7 | "homepage": "https://github.com/apps/changeset-bot", 8 | "dependencies": { 9 | "@changesets/assemble-release-plan": "^6.0.2", 10 | "@changesets/config": "^3.0.1", 11 | "@changesets/parse": "^0.4.0", 12 | "@changesets/types": "^6.0.0", 13 | "@manypkg/get-packages": "^1.1.3", 14 | "@types/bunyan": "^1.8.6", 15 | "@types/express": "^4.17.2", 16 | "@types/ioredis": "^4.14.8", 17 | "@types/js-yaml": "^3.12.2", 18 | "@types/markdown-table": "^2.0.0", 19 | "@types/micromatch": "^4.0.1", 20 | "@types/node-fetch": "^2.5.5", 21 | "@types/react": "^18.0.14", 22 | "@types/react-dom": "^18.0.5", 23 | "human-id": "^1.0.2", 24 | "js-yaml": "^3.14.0", 25 | "markdown-table": "^2.0.0", 26 | "next": "^12.1.6", 27 | "node-fetch": "^2.6.1", 28 | "path": "^0.12.7", 29 | "probot": "^12.2.4", 30 | "react": "^18.2.0", 31 | "react-dom": "^18.2.0", 32 | "typescript": "^4.7.4" 33 | }, 34 | "devDependencies": { 35 | "jest": "^24.1.0", 36 | "nock": "^10.0.0", 37 | "outdent": "^0.7.0" 38 | }, 39 | "jest": { 40 | "testEnvironment": "node" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pages/api/webhook.ts: -------------------------------------------------------------------------------- 1 | import { createNodeMiddleware, createProbot } from "probot"; 2 | import app from "../../index"; 3 | 4 | // requires: 5 | // - APP_ID 6 | // - PRIVATE_KEY 7 | // - WEBHOOK_SECRET 8 | const probot = createProbot(); 9 | 10 | export default createNodeMiddleware(app, { 11 | probot, 12 | webhooksPath: "/api/webhook", 13 | }); 14 | -------------------------------------------------------------------------------- /test/fixtures/pull_request.opened.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "opened", 3 | "number": 2, 4 | "pull_request": { 5 | "url": "https://api.github.com/repos/changesets/bot/pulls/2", 6 | "id": 324471396, 7 | "node_id": "MDExOlB1bGxSZXF1ZXN0MzI0NDcxMzk2", 8 | "html_url": "https://github.com/changesets/bot/pull/2", 9 | "diff_url": "https://github.com/changesets/bot/pull/2.diff", 10 | "patch_url": "https://github.com/changesets/bot/pull/2.patch", 11 | "issue_url": "https://api.github.com/repos/changesets/bot/issues/2", 12 | "number": 2, 13 | "state": "open", 14 | "locked": false, 15 | "title": "thing", 16 | "user": { 17 | "login": "mitchellhamilton", 18 | "id": 11481355, 19 | "node_id": "MDQ6VXNlcjExNDgxMzU1", 20 | "avatar_url": "https://avatars1.githubusercontent.com/u/11481355?v=4", 21 | "gravatar_id": "", 22 | "url": "https://api.github.com/users/mitchellhamilton", 23 | "html_url": "https://github.com/mitchellhamilton", 24 | "followers_url": "https://api.github.com/users/mitchellhamilton/followers", 25 | "following_url": "https://api.github.com/users/mitchellhamilton/following{/other_user}", 26 | "gists_url": "https://api.github.com/users/mitchellhamilton/gists{/gist_id}", 27 | "starred_url": "https://api.github.com/users/mitchellhamilton/starred{/owner}{/repo}", 28 | "subscriptions_url": "https://api.github.com/users/mitchellhamilton/subscriptions", 29 | "organizations_url": "https://api.github.com/users/mitchellhamilton/orgs", 30 | "repos_url": "https://api.github.com/users/mitchellhamilton/repos", 31 | "events_url": "https://api.github.com/users/mitchellhamilton/events{/privacy}", 32 | "received_events_url": "https://api.github.com/users/mitchellhamilton/received_events", 33 | "type": "User", 34 | "site_admin": false 35 | }, 36 | "body": "", 37 | "created_at": "2019-10-04T01:21:34Z", 38 | "updated_at": "2019-10-04T01:21:34Z", 39 | "closed_at": null, 40 | "merged_at": null, 41 | "merge_commit_sha": null, 42 | "assignee": null, 43 | "assignees": [], 44 | "requested_reviewers": [], 45 | "requested_teams": [], 46 | "labels": [], 47 | "milestone": null, 48 | "commits_url": "https://api.github.com/repos/changesets/bot/pulls/2/commits", 49 | "review_comments_url": "https://api.github.com/repos/changesets/bot/pulls/2/comments", 50 | "review_comment_url": "https://api.github.com/repos/changesets/bot/pulls/comments{/number}", 51 | "comments_url": "https://api.github.com/repos/changesets/bot/issues/2/comments", 52 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/c4d7edfd758bd44f7d4264fb55f6033f56d79540", 53 | "head": { 54 | "label": "changesets:test", 55 | "ref": "test", 56 | "sha": "c4d7edfd758bd44f7d4264fb55f6033f56d79540", 57 | "user": { 58 | "login": "changesets", 59 | "id": 51163350, 60 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 61 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 62 | "gravatar_id": "", 63 | "url": "https://api.github.com/users/changesets", 64 | "html_url": "https://github.com/changesets", 65 | "followers_url": "https://api.github.com/users/changesets/followers", 66 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 67 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 68 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 69 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 70 | "organizations_url": "https://api.github.com/users/changesets/orgs", 71 | "repos_url": "https://api.github.com/users/changesets/repos", 72 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 73 | "received_events_url": "https://api.github.com/users/changesets/received_events", 74 | "type": "Organization", 75 | "site_admin": false 76 | }, 77 | "repo": { 78 | "id": 212706257, 79 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 80 | "name": "bot", 81 | "full_name": "changesets/bot", 82 | "private": false, 83 | "owner": { 84 | "login": "changesets", 85 | "id": 51163350, 86 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 87 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 88 | "gravatar_id": "", 89 | "url": "https://api.github.com/users/changesets", 90 | "html_url": "https://github.com/changesets", 91 | "followers_url": "https://api.github.com/users/changesets/followers", 92 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 93 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 94 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 95 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 96 | "organizations_url": "https://api.github.com/users/changesets/orgs", 97 | "repos_url": "https://api.github.com/users/changesets/repos", 98 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 99 | "received_events_url": "https://api.github.com/users/changesets/received_events", 100 | "type": "Organization", 101 | "site_admin": false 102 | }, 103 | "html_url": "https://github.com/changesets/bot", 104 | "description": null, 105 | "fork": false, 106 | "url": "https://api.github.com/repos/changesets/bot", 107 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 108 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 109 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 110 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 111 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 112 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 113 | "events_url": "https://api.github.com/repos/changesets/bot/events", 114 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 115 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 116 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 117 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 118 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 119 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 120 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 121 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 122 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 123 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 124 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 125 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 126 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 127 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 128 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 129 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 130 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 131 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 132 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 133 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 134 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 135 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 136 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 137 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 138 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 139 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 140 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 141 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 142 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 143 | "created_at": "2019-10-04T00:19:38Z", 144 | "updated_at": "2019-10-04T01:19:46Z", 145 | "pushed_at": "2019-10-04T01:21:14Z", 146 | "git_url": "git://github.com/changesets/bot.git", 147 | "ssh_url": "git@github.com:changesets/bot.git", 148 | "clone_url": "https://github.com/changesets/bot.git", 149 | "svn_url": "https://github.com/changesets/bot", 150 | "homepage": "https://changeset-bot.now.sh", 151 | "size": 0, 152 | "stargazers_count": 0, 153 | "watchers_count": 0, 154 | "language": "JavaScript", 155 | "has_issues": true, 156 | "has_projects": true, 157 | "has_downloads": true, 158 | "has_wiki": true, 159 | "has_pages": false, 160 | "forks_count": 0, 161 | "mirror_url": null, 162 | "archived": false, 163 | "disabled": false, 164 | "open_issues_count": 1, 165 | "license": null, 166 | "forks": 0, 167 | "open_issues": 1, 168 | "watchers": 0, 169 | "default_branch": "master" 170 | } 171 | }, 172 | "base": { 173 | "label": "changesets:master", 174 | "ref": "master", 175 | "sha": "ddc69e35c1a8647d466d0677c84035a60bd8b100", 176 | "user": { 177 | "login": "changesets", 178 | "id": 51163350, 179 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 180 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 181 | "gravatar_id": "", 182 | "url": "https://api.github.com/users/changesets", 183 | "html_url": "https://github.com/changesets", 184 | "followers_url": "https://api.github.com/users/changesets/followers", 185 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 186 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 187 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 188 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 189 | "organizations_url": "https://api.github.com/users/changesets/orgs", 190 | "repos_url": "https://api.github.com/users/changesets/repos", 191 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 192 | "received_events_url": "https://api.github.com/users/changesets/received_events", 193 | "type": "Organization", 194 | "site_admin": false 195 | }, 196 | "repo": { 197 | "id": 212706257, 198 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 199 | "name": "bot", 200 | "full_name": "changesets/bot", 201 | "private": false, 202 | "owner": { 203 | "login": "changesets", 204 | "id": 51163350, 205 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 206 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 207 | "gravatar_id": "", 208 | "url": "https://api.github.com/users/changesets", 209 | "html_url": "https://github.com/changesets", 210 | "followers_url": "https://api.github.com/users/changesets/followers", 211 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 212 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 213 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 214 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 215 | "organizations_url": "https://api.github.com/users/changesets/orgs", 216 | "repos_url": "https://api.github.com/users/changesets/repos", 217 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 218 | "received_events_url": "https://api.github.com/users/changesets/received_events", 219 | "type": "Organization", 220 | "site_admin": false 221 | }, 222 | "html_url": "https://github.com/changesets/bot", 223 | "description": null, 224 | "fork": false, 225 | "url": "https://api.github.com/repos/changesets/bot", 226 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 227 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 228 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 229 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 230 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 231 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 232 | "events_url": "https://api.github.com/repos/changesets/bot/events", 233 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 234 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 235 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 236 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 237 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 238 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 239 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 240 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 241 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 242 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 243 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 244 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 245 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 246 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 247 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 248 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 249 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 250 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 251 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 252 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 253 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 254 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 255 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 256 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 257 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 258 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 259 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 260 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 261 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 262 | "created_at": "2019-10-04T00:19:38Z", 263 | "updated_at": "2019-10-04T01:19:46Z", 264 | "pushed_at": "2019-10-04T01:21:14Z", 265 | "git_url": "git://github.com/changesets/bot.git", 266 | "ssh_url": "git@github.com:changesets/bot.git", 267 | "clone_url": "https://github.com/changesets/bot.git", 268 | "svn_url": "https://github.com/changesets/bot", 269 | "homepage": "https://changeset-bot.now.sh", 270 | "size": 0, 271 | "stargazers_count": 0, 272 | "watchers_count": 0, 273 | "language": "JavaScript", 274 | "has_issues": true, 275 | "has_projects": true, 276 | "has_downloads": true, 277 | "has_wiki": true, 278 | "has_pages": false, 279 | "forks_count": 0, 280 | "mirror_url": null, 281 | "archived": false, 282 | "disabled": false, 283 | "open_issues_count": 1, 284 | "license": null, 285 | "forks": 0, 286 | "open_issues": 1, 287 | "watchers": 0, 288 | "default_branch": "master" 289 | } 290 | }, 291 | "_links": { 292 | "self": { 293 | "href": "https://api.github.com/repos/changesets/bot/pulls/2" 294 | }, 295 | "html": { 296 | "href": "https://github.com/changesets/bot/pull/2" 297 | }, 298 | "issue": { 299 | "href": "https://api.github.com/repos/changesets/bot/issues/2" 300 | }, 301 | "comments": { 302 | "href": "https://api.github.com/repos/changesets/bot/issues/2/comments" 303 | }, 304 | "review_comments": { 305 | "href": "https://api.github.com/repos/changesets/bot/pulls/2/comments" 306 | }, 307 | "review_comment": { 308 | "href": "https://api.github.com/repos/changesets/bot/pulls/comments{/number}" 309 | }, 310 | "commits": { 311 | "href": "https://api.github.com/repos/changesets/bot/pulls/2/commits" 312 | }, 313 | "statuses": { 314 | "href": "https://api.github.com/repos/changesets/bot/statuses/c4d7edfd758bd44f7d4264fb55f6033f56d79540" 315 | } 316 | }, 317 | "author_association": "MEMBER", 318 | "draft": false, 319 | "merged": false, 320 | "mergeable": null, 321 | "rebaseable": null, 322 | "mergeable_state": "unknown", 323 | "merged_by": null, 324 | "comments": 0, 325 | "review_comments": 0, 326 | "maintainer_can_modify": false, 327 | "commits": 1, 328 | "additions": 2, 329 | "deletions": 0, 330 | "changed_files": 1 331 | }, 332 | "repository": { 333 | "id": 212706257, 334 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 335 | "name": "bot", 336 | "full_name": "changesets/bot", 337 | "private": false, 338 | "owner": { 339 | "login": "changesets", 340 | "id": 51163350, 341 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 342 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 343 | "gravatar_id": "", 344 | "url": "https://api.github.com/users/changesets", 345 | "html_url": "https://github.com/changesets", 346 | "followers_url": "https://api.github.com/users/changesets/followers", 347 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 348 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 349 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 350 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 351 | "organizations_url": "https://api.github.com/users/changesets/orgs", 352 | "repos_url": "https://api.github.com/users/changesets/repos", 353 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 354 | "received_events_url": "https://api.github.com/users/changesets/received_events", 355 | "type": "Organization", 356 | "site_admin": false 357 | }, 358 | "html_url": "https://github.com/changesets/bot", 359 | "description": null, 360 | "fork": false, 361 | "url": "https://api.github.com/repos/changesets/bot", 362 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 363 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 364 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 365 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 366 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 367 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 368 | "events_url": "https://api.github.com/repos/changesets/bot/events", 369 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 370 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 371 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 372 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 373 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 374 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 375 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 376 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 377 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 378 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 379 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 380 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 381 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 382 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 383 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 384 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 385 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 386 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 387 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 388 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 389 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 390 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 391 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 392 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 393 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 394 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 395 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 396 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 397 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 398 | "created_at": "2019-10-04T00:19:38Z", 399 | "updated_at": "2019-10-04T01:19:46Z", 400 | "pushed_at": "2019-10-04T01:21:14Z", 401 | "git_url": "git://github.com/changesets/bot.git", 402 | "ssh_url": "git@github.com:changesets/bot.git", 403 | "clone_url": "https://github.com/changesets/bot.git", 404 | "svn_url": "https://github.com/changesets/bot", 405 | "homepage": "https://changeset-bot.now.sh", 406 | "size": 0, 407 | "stargazers_count": 0, 408 | "watchers_count": 0, 409 | "language": "JavaScript", 410 | "has_issues": true, 411 | "has_projects": true, 412 | "has_downloads": true, 413 | "has_wiki": true, 414 | "has_pages": false, 415 | "forks_count": 0, 416 | "mirror_url": null, 417 | "archived": false, 418 | "disabled": false, 419 | "open_issues_count": 1, 420 | "license": null, 421 | "forks": 0, 422 | "open_issues": 1, 423 | "watchers": 0, 424 | "default_branch": "master" 425 | }, 426 | "organization": { 427 | "login": "changesets", 428 | "id": 51163350, 429 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 430 | "url": "https://api.github.com/orgs/changesets", 431 | "repos_url": "https://api.github.com/orgs/changesets/repos", 432 | "events_url": "https://api.github.com/orgs/changesets/events", 433 | "hooks_url": "https://api.github.com/orgs/changesets/hooks", 434 | "issues_url": "https://api.github.com/orgs/changesets/issues", 435 | "members_url": "https://api.github.com/orgs/changesets/members{/member}", 436 | "public_members_url": "https://api.github.com/orgs/changesets/public_members{/member}", 437 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 438 | "description": null 439 | }, 440 | "sender": { 441 | "login": "mitchellhamilton", 442 | "id": 11481355, 443 | "node_id": "MDQ6VXNlcjExNDgxMzU1", 444 | "avatar_url": "https://avatars1.githubusercontent.com/u/11481355?v=4", 445 | "gravatar_id": "", 446 | "url": "https://api.github.com/users/mitchellhamilton", 447 | "html_url": "https://github.com/mitchellhamilton", 448 | "followers_url": "https://api.github.com/users/mitchellhamilton/followers", 449 | "following_url": "https://api.github.com/users/mitchellhamilton/following{/other_user}", 450 | "gists_url": "https://api.github.com/users/mitchellhamilton/gists{/gist_id}", 451 | "starred_url": "https://api.github.com/users/mitchellhamilton/starred{/owner}{/repo}", 452 | "subscriptions_url": "https://api.github.com/users/mitchellhamilton/subscriptions", 453 | "organizations_url": "https://api.github.com/users/mitchellhamilton/orgs", 454 | "repos_url": "https://api.github.com/users/mitchellhamilton/repos", 455 | "events_url": "https://api.github.com/users/mitchellhamilton/events{/privacy}", 456 | "received_events_url": "https://api.github.com/users/mitchellhamilton/received_events", 457 | "type": "User", 458 | "site_admin": false 459 | }, 460 | "installation": { 461 | "id": 2462428, 462 | "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMjQ2MjQyOA==" 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /test/fixtures/pull_request.synchronize.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "synchronize", 3 | "number": 2, 4 | "pull_request": { 5 | "url": "https://api.github.com/repos/changesets/bot/pulls/2", 6 | "id": 324471396, 7 | "node_id": "MDExOlB1bGxSZXF1ZXN0MzI0NDcxMzk2", 8 | "html_url": "https://github.com/changesets/bot/pull/2", 9 | "diff_url": "https://github.com/changesets/bot/pull/2.diff", 10 | "patch_url": "https://github.com/changesets/bot/pull/2.patch", 11 | "issue_url": "https://api.github.com/repos/changesets/bot/issues/2", 12 | "number": 2, 13 | "state": "open", 14 | "locked": false, 15 | "title": "thing", 16 | "user": { 17 | "login": "mitchellhamilton", 18 | "id": 11481355, 19 | "node_id": "MDQ6VXNlcjExNDgxMzU1", 20 | "avatar_url": "https://avatars1.githubusercontent.com/u/11481355?v=4", 21 | "gravatar_id": "", 22 | "url": "https://api.github.com/users/mitchellhamilton", 23 | "html_url": "https://github.com/mitchellhamilton", 24 | "followers_url": "https://api.github.com/users/mitchellhamilton/followers", 25 | "following_url": "https://api.github.com/users/mitchellhamilton/following{/other_user}", 26 | "gists_url": "https://api.github.com/users/mitchellhamilton/gists{/gist_id}", 27 | "starred_url": "https://api.github.com/users/mitchellhamilton/starred{/owner}{/repo}", 28 | "subscriptions_url": "https://api.github.com/users/mitchellhamilton/subscriptions", 29 | "organizations_url": "https://api.github.com/users/mitchellhamilton/orgs", 30 | "repos_url": "https://api.github.com/users/mitchellhamilton/repos", 31 | "events_url": "https://api.github.com/users/mitchellhamilton/events{/privacy}", 32 | "received_events_url": "https://api.github.com/users/mitchellhamilton/received_events", 33 | "type": "User", 34 | "site_admin": false 35 | }, 36 | "body": "", 37 | "created_at": "2019-10-04T01:21:34Z", 38 | "updated_at": "2019-10-04T01:23:56Z", 39 | "closed_at": null, 40 | "merged_at": null, 41 | "merge_commit_sha": "2d1821fdc425152fc0bd1691546c9d76db6e0f23", 42 | "assignee": null, 43 | "assignees": [ 44 | 45 | ], 46 | "requested_reviewers": [ 47 | 48 | ], 49 | "requested_teams": [ 50 | 51 | ], 52 | "labels": [ 53 | 54 | ], 55 | "milestone": null, 56 | "commits_url": "https://api.github.com/repos/changesets/bot/pulls/2/commits", 57 | "review_comments_url": "https://api.github.com/repos/changesets/bot/pulls/2/comments", 58 | "review_comment_url": "https://api.github.com/repos/changesets/bot/pulls/comments{/number}", 59 | "comments_url": "https://api.github.com/repos/changesets/bot/issues/2/comments", 60 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/10a63035fe8155b86b1060c89873e9a03c6fe673", 61 | "head": { 62 | "label": "changesets:test", 63 | "ref": "test", 64 | "sha": "10a63035fe8155b86b1060c89873e9a03c6fe673", 65 | "user": { 66 | "login": "changesets", 67 | "id": 51163350, 68 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 69 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 70 | "gravatar_id": "", 71 | "url": "https://api.github.com/users/changesets", 72 | "html_url": "https://github.com/changesets", 73 | "followers_url": "https://api.github.com/users/changesets/followers", 74 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 75 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 76 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 77 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 78 | "organizations_url": "https://api.github.com/users/changesets/orgs", 79 | "repos_url": "https://api.github.com/users/changesets/repos", 80 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 81 | "received_events_url": "https://api.github.com/users/changesets/received_events", 82 | "type": "Organization", 83 | "site_admin": false 84 | }, 85 | "repo": { 86 | "id": 212706257, 87 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 88 | "name": "bot", 89 | "full_name": "changesets/bot", 90 | "private": false, 91 | "owner": { 92 | "login": "changesets", 93 | "id": 51163350, 94 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 95 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 96 | "gravatar_id": "", 97 | "url": "https://api.github.com/users/changesets", 98 | "html_url": "https://github.com/changesets", 99 | "followers_url": "https://api.github.com/users/changesets/followers", 100 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 101 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 102 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 103 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 104 | "organizations_url": "https://api.github.com/users/changesets/orgs", 105 | "repos_url": "https://api.github.com/users/changesets/repos", 106 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 107 | "received_events_url": "https://api.github.com/users/changesets/received_events", 108 | "type": "Organization", 109 | "site_admin": false 110 | }, 111 | "html_url": "https://github.com/changesets/bot", 112 | "description": null, 113 | "fork": false, 114 | "url": "https://api.github.com/repos/changesets/bot", 115 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 116 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 117 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 118 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 119 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 120 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 121 | "events_url": "https://api.github.com/repos/changesets/bot/events", 122 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 123 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 124 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 125 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 126 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 127 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 128 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 129 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 130 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 131 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 132 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 133 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 134 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 135 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 136 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 137 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 138 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 139 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 140 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 141 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 142 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 143 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 144 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 145 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 146 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 147 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 148 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 149 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 150 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 151 | "created_at": "2019-10-04T00:19:38Z", 152 | "updated_at": "2019-10-04T01:19:46Z", 153 | "pushed_at": "2019-10-04T01:23:56Z", 154 | "git_url": "git://github.com/changesets/bot.git", 155 | "ssh_url": "git@github.com:changesets/bot.git", 156 | "clone_url": "https://github.com/changesets/bot.git", 157 | "svn_url": "https://github.com/changesets/bot", 158 | "homepage": "https://changeset-bot.now.sh", 159 | "size": 0, 160 | "stargazers_count": 0, 161 | "watchers_count": 0, 162 | "language": "JavaScript", 163 | "has_issues": true, 164 | "has_projects": true, 165 | "has_downloads": true, 166 | "has_wiki": true, 167 | "has_pages": false, 168 | "forks_count": 0, 169 | "mirror_url": null, 170 | "archived": false, 171 | "disabled": false, 172 | "open_issues_count": 1, 173 | "license": null, 174 | "forks": 0, 175 | "open_issues": 1, 176 | "watchers": 0, 177 | "default_branch": "master" 178 | } 179 | }, 180 | "base": { 181 | "label": "changesets:master", 182 | "ref": "master", 183 | "sha": "ddc69e35c1a8647d466d0677c84035a60bd8b100", 184 | "user": { 185 | "login": "changesets", 186 | "id": 51163350, 187 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 188 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 189 | "gravatar_id": "", 190 | "url": "https://api.github.com/users/changesets", 191 | "html_url": "https://github.com/changesets", 192 | "followers_url": "https://api.github.com/users/changesets/followers", 193 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 194 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 195 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 196 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 197 | "organizations_url": "https://api.github.com/users/changesets/orgs", 198 | "repos_url": "https://api.github.com/users/changesets/repos", 199 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 200 | "received_events_url": "https://api.github.com/users/changesets/received_events", 201 | "type": "Organization", 202 | "site_admin": false 203 | }, 204 | "repo": { 205 | "id": 212706257, 206 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 207 | "name": "bot", 208 | "full_name": "changesets/bot", 209 | "private": false, 210 | "owner": { 211 | "login": "changesets", 212 | "id": 51163350, 213 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 214 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 215 | "gravatar_id": "", 216 | "url": "https://api.github.com/users/changesets", 217 | "html_url": "https://github.com/changesets", 218 | "followers_url": "https://api.github.com/users/changesets/followers", 219 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 220 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 221 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 222 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 223 | "organizations_url": "https://api.github.com/users/changesets/orgs", 224 | "repos_url": "https://api.github.com/users/changesets/repos", 225 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 226 | "received_events_url": "https://api.github.com/users/changesets/received_events", 227 | "type": "Organization", 228 | "site_admin": false 229 | }, 230 | "html_url": "https://github.com/changesets/bot", 231 | "description": null, 232 | "fork": false, 233 | "url": "https://api.github.com/repos/changesets/bot", 234 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 235 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 236 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 237 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 238 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 239 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 240 | "events_url": "https://api.github.com/repos/changesets/bot/events", 241 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 242 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 243 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 244 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 245 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 246 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 247 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 248 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 249 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 250 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 251 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 252 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 253 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 254 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 255 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 256 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 257 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 258 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 259 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 260 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 261 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 262 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 263 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 264 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 265 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 266 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 267 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 268 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 269 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 270 | "created_at": "2019-10-04T00:19:38Z", 271 | "updated_at": "2019-10-04T01:19:46Z", 272 | "pushed_at": "2019-10-04T01:23:56Z", 273 | "git_url": "git://github.com/changesets/bot.git", 274 | "ssh_url": "git@github.com:changesets/bot.git", 275 | "clone_url": "https://github.com/changesets/bot.git", 276 | "svn_url": "https://github.com/changesets/bot", 277 | "homepage": "https://changeset-bot.now.sh", 278 | "size": 0, 279 | "stargazers_count": 0, 280 | "watchers_count": 0, 281 | "language": "JavaScript", 282 | "has_issues": true, 283 | "has_projects": true, 284 | "has_downloads": true, 285 | "has_wiki": true, 286 | "has_pages": false, 287 | "forks_count": 0, 288 | "mirror_url": null, 289 | "archived": false, 290 | "disabled": false, 291 | "open_issues_count": 1, 292 | "license": null, 293 | "forks": 0, 294 | "open_issues": 1, 295 | "watchers": 0, 296 | "default_branch": "master" 297 | } 298 | }, 299 | "_links": { 300 | "self": { 301 | "href": "https://api.github.com/repos/changesets/bot/pulls/2" 302 | }, 303 | "html": { 304 | "href": "https://github.com/changesets/bot/pull/2" 305 | }, 306 | "issue": { 307 | "href": "https://api.github.com/repos/changesets/bot/issues/2" 308 | }, 309 | "comments": { 310 | "href": "https://api.github.com/repos/changesets/bot/issues/2/comments" 311 | }, 312 | "review_comments": { 313 | "href": "https://api.github.com/repos/changesets/bot/pulls/2/comments" 314 | }, 315 | "review_comment": { 316 | "href": "https://api.github.com/repos/changesets/bot/pulls/comments{/number}" 317 | }, 318 | "commits": { 319 | "href": "https://api.github.com/repos/changesets/bot/pulls/2/commits" 320 | }, 321 | "statuses": { 322 | "href": "https://api.github.com/repos/changesets/bot/statuses/10a63035fe8155b86b1060c89873e9a03c6fe673" 323 | } 324 | }, 325 | "author_association": "MEMBER", 326 | "draft": false, 327 | "merged": false, 328 | "mergeable": null, 329 | "rebaseable": null, 330 | "mergeable_state": "unknown", 331 | "merged_by": null, 332 | "comments": 3, 333 | "review_comments": 0, 334 | "maintainer_can_modify": false, 335 | "commits": 2, 336 | "additions": 3, 337 | "deletions": 1, 338 | "changed_files": 2 339 | }, 340 | "before": "c4d7edfd758bd44f7d4264fb55f6033f56d79540", 341 | "after": "10a63035fe8155b86b1060c89873e9a03c6fe673", 342 | "repository": { 343 | "id": 212706257, 344 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 345 | "name": "bot", 346 | "full_name": "changesets/bot", 347 | "private": false, 348 | "owner": { 349 | "login": "changesets", 350 | "id": 51163350, 351 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 352 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 353 | "gravatar_id": "", 354 | "url": "https://api.github.com/users/changesets", 355 | "html_url": "https://github.com/changesets", 356 | "followers_url": "https://api.github.com/users/changesets/followers", 357 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 358 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 359 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 360 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 361 | "organizations_url": "https://api.github.com/users/changesets/orgs", 362 | "repos_url": "https://api.github.com/users/changesets/repos", 363 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 364 | "received_events_url": "https://api.github.com/users/changesets/received_events", 365 | "type": "Organization", 366 | "site_admin": false 367 | }, 368 | "html_url": "https://github.com/changesets/bot", 369 | "description": null, 370 | "fork": false, 371 | "url": "https://api.github.com/repos/changesets/bot", 372 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 373 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 374 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 375 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 376 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 377 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 378 | "events_url": "https://api.github.com/repos/changesets/bot/events", 379 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 380 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 381 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 382 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 383 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 384 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 385 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 386 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 387 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 388 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 389 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 390 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 391 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 392 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 393 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 394 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 395 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 396 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 397 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 398 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 399 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 400 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 401 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 402 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 403 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 404 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 405 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 406 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 407 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 408 | "created_at": "2019-10-04T00:19:38Z", 409 | "updated_at": "2019-10-04T01:19:46Z", 410 | "pushed_at": "2019-10-04T01:23:56Z", 411 | "git_url": "git://github.com/changesets/bot.git", 412 | "ssh_url": "git@github.com:changesets/bot.git", 413 | "clone_url": "https://github.com/changesets/bot.git", 414 | "svn_url": "https://github.com/changesets/bot", 415 | "homepage": "https://changeset-bot.now.sh", 416 | "size": 0, 417 | "stargazers_count": 0, 418 | "watchers_count": 0, 419 | "language": "JavaScript", 420 | "has_issues": true, 421 | "has_projects": true, 422 | "has_downloads": true, 423 | "has_wiki": true, 424 | "has_pages": false, 425 | "forks_count": 0, 426 | "mirror_url": null, 427 | "archived": false, 428 | "disabled": false, 429 | "open_issues_count": 1, 430 | "license": null, 431 | "forks": 0, 432 | "open_issues": 1, 433 | "watchers": 0, 434 | "default_branch": "master" 435 | }, 436 | "organization": { 437 | "login": "changesets", 438 | "id": 51163350, 439 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 440 | "url": "https://api.github.com/orgs/changesets", 441 | "repos_url": "https://api.github.com/orgs/changesets/repos", 442 | "events_url": "https://api.github.com/orgs/changesets/events", 443 | "hooks_url": "https://api.github.com/orgs/changesets/hooks", 444 | "issues_url": "https://api.github.com/orgs/changesets/issues", 445 | "members_url": "https://api.github.com/orgs/changesets/members{/member}", 446 | "public_members_url": "https://api.github.com/orgs/changesets/public_members{/member}", 447 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 448 | "description": null 449 | }, 450 | "sender": { 451 | "login": "mitchellhamilton", 452 | "id": 11481355, 453 | "node_id": "MDQ6VXNlcjExNDgxMzU1", 454 | "avatar_url": "https://avatars1.githubusercontent.com/u/11481355?v=4", 455 | "gravatar_id": "", 456 | "url": "https://api.github.com/users/mitchellhamilton", 457 | "html_url": "https://github.com/mitchellhamilton", 458 | "followers_url": "https://api.github.com/users/mitchellhamilton/followers", 459 | "following_url": "https://api.github.com/users/mitchellhamilton/following{/other_user}", 460 | "gists_url": "https://api.github.com/users/mitchellhamilton/gists{/gist_id}", 461 | "starred_url": "https://api.github.com/users/mitchellhamilton/starred{/owner}{/repo}", 462 | "subscriptions_url": "https://api.github.com/users/mitchellhamilton/subscriptions", 463 | "organizations_url": "https://api.github.com/users/mitchellhamilton/orgs", 464 | "repos_url": "https://api.github.com/users/mitchellhamilton/repos", 465 | "events_url": "https://api.github.com/users/mitchellhamilton/events{/privacy}", 466 | "received_events_url": "https://api.github.com/users/mitchellhamilton/received_events", 467 | "type": "User", 468 | "site_admin": false 469 | }, 470 | "installation": { 471 | "id": 2462428, 472 | "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMjQ2MjQyOA==" 473 | } 474 | } -------------------------------------------------------------------------------- /test/fixtures/release_pull_request.opened.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "opened", 3 | "number": 2, 4 | "pull_request": { 5 | "url": "https://api.github.com/repos/changesets/bot/pulls/2", 6 | "id": 324471396, 7 | "node_id": "MDExOlB1bGxSZXF1ZXN0MzI0NDcxMzk2", 8 | "html_url": "https://github.com/changesets/bot/pull/2", 9 | "diff_url": "https://github.com/changesets/bot/pull/2.diff", 10 | "patch_url": "https://github.com/changesets/bot/pull/2.patch", 11 | "issue_url": "https://api.github.com/repos/changesets/bot/issues/2", 12 | "number": 2, 13 | "state": "open", 14 | "locked": false, 15 | "title": "Version Packages", 16 | "user": { 17 | "login": "github-actions[bot]", 18 | "id": 41898282, 19 | "node_id": "MDM6Qm90NDE4OTgyODI=", 20 | "avatar_url": "https://avatars2.githubusercontent.com/in/15368?v=4", 21 | "gravatar_id": "", 22 | "url": "https://api.github.com/users/github-actions%5Bbot%5D", 23 | "html_url": "https://github.com/apps/github-actions", 24 | "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", 25 | "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", 26 | "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", 27 | "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", 28 | "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", 29 | "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", 30 | "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", 31 | "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", 32 | "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", 33 | "type": "Bot", 34 | "site_admin": false 35 | }, 36 | "body": "This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to master, this PR will be updated.", 37 | "created_at": "2019-10-04T01:21:34Z", 38 | "updated_at": "2019-10-04T01:21:34Z", 39 | "closed_at": null, 40 | "merged_at": null, 41 | "merge_commit_sha": null, 42 | "assignee": null, 43 | "assignees": [], 44 | "requested_reviewers": [], 45 | "requested_teams": [], 46 | "labels": [], 47 | "milestone": null, 48 | "commits_url": "https://api.github.com/repos/changesets/bot/pulls/2/commits", 49 | "review_comments_url": "https://api.github.com/repos/changesets/bot/pulls/2/comments", 50 | "review_comment_url": "https://api.github.com/repos/changesets/bot/pulls/comments{/number}", 51 | "comments_url": "https://api.github.com/repos/changesets/bot/issues/2/comments", 52 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/c4d7edfd758bd44f7d4264fb55f6033f56d79540", 53 | "head": { 54 | "label": "changesets:changeset-release", 55 | "ref": "changeset-release", 56 | "sha": "c4d7edfd758bd44f7d4264fb55f6033f56d79540", 57 | "user": { 58 | "login": "changesets", 59 | "id": 51163350, 60 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 61 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 62 | "gravatar_id": "", 63 | "url": "https://api.github.com/users/changesets", 64 | "html_url": "https://github.com/changesets", 65 | "followers_url": "https://api.github.com/users/changesets/followers", 66 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 67 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 68 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 69 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 70 | "organizations_url": "https://api.github.com/users/changesets/orgs", 71 | "repos_url": "https://api.github.com/users/changesets/repos", 72 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 73 | "received_events_url": "https://api.github.com/users/changesets/received_events", 74 | "type": "Organization", 75 | "site_admin": false 76 | }, 77 | "repo": { 78 | "id": 212706257, 79 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 80 | "name": "bot", 81 | "full_name": "changesets/bot", 82 | "private": false, 83 | "owner": { 84 | "login": "changesets", 85 | "id": 51163350, 86 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 87 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 88 | "gravatar_id": "", 89 | "url": "https://api.github.com/users/changesets", 90 | "html_url": "https://github.com/changesets", 91 | "followers_url": "https://api.github.com/users/changesets/followers", 92 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 93 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 94 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 95 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 96 | "organizations_url": "https://api.github.com/users/changesets/orgs", 97 | "repos_url": "https://api.github.com/users/changesets/repos", 98 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 99 | "received_events_url": "https://api.github.com/users/changesets/received_events", 100 | "type": "Organization", 101 | "site_admin": false 102 | }, 103 | "html_url": "https://github.com/changesets/bot", 104 | "description": null, 105 | "fork": false, 106 | "url": "https://api.github.com/repos/changesets/bot", 107 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 108 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 109 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 110 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 111 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 112 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 113 | "events_url": "https://api.github.com/repos/changesets/bot/events", 114 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 115 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 116 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 117 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 118 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 119 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 120 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 121 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 122 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 123 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 124 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 125 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 126 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 127 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 128 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 129 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 130 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 131 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 132 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 133 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 134 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 135 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 136 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 137 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 138 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 139 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 140 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 141 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 142 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 143 | "created_at": "2019-10-04T00:19:38Z", 144 | "updated_at": "2019-10-04T01:19:46Z", 145 | "pushed_at": "2019-10-04T01:21:14Z", 146 | "git_url": "git://github.com/changesets/bot.git", 147 | "ssh_url": "git@github.com:changesets/bot.git", 148 | "clone_url": "https://github.com/changesets/bot.git", 149 | "svn_url": "https://github.com/changesets/bot", 150 | "homepage": "https://changeset-bot.now.sh", 151 | "size": 0, 152 | "stargazers_count": 0, 153 | "watchers_count": 0, 154 | "language": "JavaScript", 155 | "has_issues": true, 156 | "has_projects": true, 157 | "has_downloads": true, 158 | "has_wiki": true, 159 | "has_pages": false, 160 | "forks_count": 0, 161 | "mirror_url": null, 162 | "archived": false, 163 | "disabled": false, 164 | "open_issues_count": 1, 165 | "license": null, 166 | "forks": 0, 167 | "open_issues": 1, 168 | "watchers": 0, 169 | "default_branch": "master" 170 | } 171 | }, 172 | "base": { 173 | "label": "changesets:master", 174 | "ref": "master", 175 | "sha": "ddc69e35c1a8647d466d0677c84035a60bd8b100", 176 | "user": { 177 | "login": "changesets", 178 | "id": 51163350, 179 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 180 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 181 | "gravatar_id": "", 182 | "url": "https://api.github.com/users/changesets", 183 | "html_url": "https://github.com/changesets", 184 | "followers_url": "https://api.github.com/users/changesets/followers", 185 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 186 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 187 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 188 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 189 | "organizations_url": "https://api.github.com/users/changesets/orgs", 190 | "repos_url": "https://api.github.com/users/changesets/repos", 191 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 192 | "received_events_url": "https://api.github.com/users/changesets/received_events", 193 | "type": "Organization", 194 | "site_admin": false 195 | }, 196 | "repo": { 197 | "id": 212706257, 198 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 199 | "name": "bot", 200 | "full_name": "changesets/bot", 201 | "private": false, 202 | "owner": { 203 | "login": "changesets", 204 | "id": 51163350, 205 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 206 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 207 | "gravatar_id": "", 208 | "url": "https://api.github.com/users/changesets", 209 | "html_url": "https://github.com/changesets", 210 | "followers_url": "https://api.github.com/users/changesets/followers", 211 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 212 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 213 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 214 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 215 | "organizations_url": "https://api.github.com/users/changesets/orgs", 216 | "repos_url": "https://api.github.com/users/changesets/repos", 217 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 218 | "received_events_url": "https://api.github.com/users/changesets/received_events", 219 | "type": "Organization", 220 | "site_admin": false 221 | }, 222 | "html_url": "https://github.com/changesets/bot", 223 | "description": null, 224 | "fork": false, 225 | "url": "https://api.github.com/repos/changesets/bot", 226 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 227 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 228 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 229 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 230 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 231 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 232 | "events_url": "https://api.github.com/repos/changesets/bot/events", 233 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 234 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 235 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 236 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 237 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 238 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 239 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 240 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 241 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 242 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 243 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 244 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 245 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 246 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 247 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 248 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 249 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 250 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 251 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 252 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 253 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 254 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 255 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 256 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 257 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 258 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 259 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 260 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 261 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 262 | "created_at": "2019-10-04T00:19:38Z", 263 | "updated_at": "2019-10-04T01:19:46Z", 264 | "pushed_at": "2019-10-04T01:21:14Z", 265 | "git_url": "git://github.com/changesets/bot.git", 266 | "ssh_url": "git@github.com:changesets/bot.git", 267 | "clone_url": "https://github.com/changesets/bot.git", 268 | "svn_url": "https://github.com/changesets/bot", 269 | "homepage": "https://changeset-bot.now.sh", 270 | "size": 0, 271 | "stargazers_count": 0, 272 | "watchers_count": 0, 273 | "language": "JavaScript", 274 | "has_issues": true, 275 | "has_projects": true, 276 | "has_downloads": true, 277 | "has_wiki": true, 278 | "has_pages": false, 279 | "forks_count": 0, 280 | "mirror_url": null, 281 | "archived": false, 282 | "disabled": false, 283 | "open_issues_count": 1, 284 | "license": null, 285 | "forks": 0, 286 | "open_issues": 1, 287 | "watchers": 0, 288 | "default_branch": "master" 289 | } 290 | }, 291 | "_links": { 292 | "self": { 293 | "href": "https://api.github.com/repos/changesets/bot/pulls/2" 294 | }, 295 | "html": { 296 | "href": "https://github.com/changesets/bot/pull/2" 297 | }, 298 | "issue": { 299 | "href": "https://api.github.com/repos/changesets/bot/issues/2" 300 | }, 301 | "comments": { 302 | "href": "https://api.github.com/repos/changesets/bot/issues/2/comments" 303 | }, 304 | "review_comments": { 305 | "href": "https://api.github.com/repos/changesets/bot/pulls/2/comments" 306 | }, 307 | "review_comment": { 308 | "href": "https://api.github.com/repos/changesets/bot/pulls/comments{/number}" 309 | }, 310 | "commits": { 311 | "href": "https://api.github.com/repos/changesets/bot/pulls/2/commits" 312 | }, 313 | "statuses": { 314 | "href": "https://api.github.com/repos/changesets/bot/statuses/c4d7edfd758bd44f7d4264fb55f6033f56d79540" 315 | } 316 | }, 317 | "author_association": "MEMBER", 318 | "draft": false, 319 | "merged": false, 320 | "mergeable": null, 321 | "rebaseable": null, 322 | "mergeable_state": "unknown", 323 | "merged_by": null, 324 | "comments": 0, 325 | "review_comments": 0, 326 | "maintainer_can_modify": false, 327 | "commits": 1, 328 | "additions": 2, 329 | "deletions": 0, 330 | "changed_files": 1 331 | }, 332 | "repository": { 333 | "id": 212706257, 334 | "node_id": "MDEwOlJlcG9zaXRvcnkyMTI3MDYyNTc=", 335 | "name": "bot", 336 | "full_name": "changesets/bot", 337 | "private": false, 338 | "owner": { 339 | "login": "changesets", 340 | "id": 51163350, 341 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 342 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 343 | "gravatar_id": "", 344 | "url": "https://api.github.com/users/changesets", 345 | "html_url": "https://github.com/changesets", 346 | "followers_url": "https://api.github.com/users/changesets/followers", 347 | "following_url": "https://api.github.com/users/changesets/following{/other_user}", 348 | "gists_url": "https://api.github.com/users/changesets/gists{/gist_id}", 349 | "starred_url": "https://api.github.com/users/changesets/starred{/owner}{/repo}", 350 | "subscriptions_url": "https://api.github.com/users/changesets/subscriptions", 351 | "organizations_url": "https://api.github.com/users/changesets/orgs", 352 | "repos_url": "https://api.github.com/users/changesets/repos", 353 | "events_url": "https://api.github.com/users/changesets/events{/privacy}", 354 | "received_events_url": "https://api.github.com/users/changesets/received_events", 355 | "type": "Organization", 356 | "site_admin": false 357 | }, 358 | "html_url": "https://github.com/changesets/bot", 359 | "description": null, 360 | "fork": false, 361 | "url": "https://api.github.com/repos/changesets/bot", 362 | "forks_url": "https://api.github.com/repos/changesets/bot/forks", 363 | "keys_url": "https://api.github.com/repos/changesets/bot/keys{/key_id}", 364 | "collaborators_url": "https://api.github.com/repos/changesets/bot/collaborators{/collaborator}", 365 | "teams_url": "https://api.github.com/repos/changesets/bot/teams", 366 | "hooks_url": "https://api.github.com/repos/changesets/bot/hooks", 367 | "issue_events_url": "https://api.github.com/repos/changesets/bot/issues/events{/number}", 368 | "events_url": "https://api.github.com/repos/changesets/bot/events", 369 | "assignees_url": "https://api.github.com/repos/changesets/bot/assignees{/user}", 370 | "branches_url": "https://api.github.com/repos/changesets/bot/branches{/branch}", 371 | "tags_url": "https://api.github.com/repos/changesets/bot/tags", 372 | "blobs_url": "https://api.github.com/repos/changesets/bot/git/blobs{/sha}", 373 | "git_tags_url": "https://api.github.com/repos/changesets/bot/git/tags{/sha}", 374 | "git_refs_url": "https://api.github.com/repos/changesets/bot/git/refs{/sha}", 375 | "trees_url": "https://api.github.com/repos/changesets/bot/git/trees{/sha}", 376 | "statuses_url": "https://api.github.com/repos/changesets/bot/statuses/{sha}", 377 | "languages_url": "https://api.github.com/repos/changesets/bot/languages", 378 | "stargazers_url": "https://api.github.com/repos/changesets/bot/stargazers", 379 | "contributors_url": "https://api.github.com/repos/changesets/bot/contributors", 380 | "subscribers_url": "https://api.github.com/repos/changesets/bot/subscribers", 381 | "subscription_url": "https://api.github.com/repos/changesets/bot/subscription", 382 | "commits_url": "https://api.github.com/repos/changesets/bot/commits{/sha}", 383 | "git_commits_url": "https://api.github.com/repos/changesets/bot/git/commits{/sha}", 384 | "comments_url": "https://api.github.com/repos/changesets/bot/comments{/number}", 385 | "issue_comment_url": "https://api.github.com/repos/changesets/bot/issues/comments{/number}", 386 | "contents_url": "https://api.github.com/repos/changesets/bot/contents/{+path}", 387 | "compare_url": "https://api.github.com/repos/changesets/bot/compare/{base}...{head}", 388 | "merges_url": "https://api.github.com/repos/changesets/bot/merges", 389 | "archive_url": "https://api.github.com/repos/changesets/bot/{archive_format}{/ref}", 390 | "downloads_url": "https://api.github.com/repos/changesets/bot/downloads", 391 | "issues_url": "https://api.github.com/repos/changesets/bot/issues{/number}", 392 | "pulls_url": "https://api.github.com/repos/changesets/bot/pulls{/number}", 393 | "milestones_url": "https://api.github.com/repos/changesets/bot/milestones{/number}", 394 | "notifications_url": "https://api.github.com/repos/changesets/bot/notifications{?since,all,participating}", 395 | "labels_url": "https://api.github.com/repos/changesets/bot/labels{/name}", 396 | "releases_url": "https://api.github.com/repos/changesets/bot/releases{/id}", 397 | "deployments_url": "https://api.github.com/repos/changesets/bot/deployments", 398 | "created_at": "2019-10-04T00:19:38Z", 399 | "updated_at": "2019-10-04T01:19:46Z", 400 | "pushed_at": "2019-10-04T01:21:14Z", 401 | "git_url": "git://github.com/changesets/bot.git", 402 | "ssh_url": "git@github.com:changesets/bot.git", 403 | "clone_url": "https://github.com/changesets/bot.git", 404 | "svn_url": "https://github.com/changesets/bot", 405 | "homepage": "https://changeset-bot.now.sh", 406 | "size": 0, 407 | "stargazers_count": 0, 408 | "watchers_count": 0, 409 | "language": "JavaScript", 410 | "has_issues": true, 411 | "has_projects": true, 412 | "has_downloads": true, 413 | "has_wiki": true, 414 | "has_pages": false, 415 | "forks_count": 0, 416 | "mirror_url": null, 417 | "archived": false, 418 | "disabled": false, 419 | "open_issues_count": 1, 420 | "license": null, 421 | "forks": 0, 422 | "open_issues": 1, 423 | "watchers": 0, 424 | "default_branch": "master" 425 | }, 426 | "organization": { 427 | "login": "changesets", 428 | "id": 51163350, 429 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxMTYzMzUw", 430 | "url": "https://api.github.com/orgs/changesets", 431 | "repos_url": "https://api.github.com/orgs/changesets/repos", 432 | "events_url": "https://api.github.com/orgs/changesets/events", 433 | "hooks_url": "https://api.github.com/orgs/changesets/hooks", 434 | "issues_url": "https://api.github.com/orgs/changesets/issues", 435 | "members_url": "https://api.github.com/orgs/changesets/members{/member}", 436 | "public_members_url": "https://api.github.com/orgs/changesets/public_members{/member}", 437 | "avatar_url": "https://avatars1.githubusercontent.com/u/51163350?v=4", 438 | "description": null 439 | }, 440 | "sender": { 441 | "login": "mitchellhamilton", 442 | "id": 11481355, 443 | "node_id": "MDQ6VXNlcjExNDgxMzU1", 444 | "avatar_url": "https://avatars1.githubusercontent.com/u/11481355?v=4", 445 | "gravatar_id": "", 446 | "url": "https://api.github.com/users/mitchellhamilton", 447 | "html_url": "https://github.com/mitchellhamilton", 448 | "followers_url": "https://api.github.com/users/mitchellhamilton/followers", 449 | "following_url": "https://api.github.com/users/mitchellhamilton/following{/other_user}", 450 | "gists_url": "https://api.github.com/users/mitchellhamilton/gists{/gist_id}", 451 | "starred_url": "https://api.github.com/users/mitchellhamilton/starred{/owner}{/repo}", 452 | "subscriptions_url": "https://api.github.com/users/mitchellhamilton/subscriptions", 453 | "organizations_url": "https://api.github.com/users/mitchellhamilton/orgs", 454 | "repos_url": "https://api.github.com/users/mitchellhamilton/repos", 455 | "events_url": "https://api.github.com/users/mitchellhamilton/events{/privacy}", 456 | "received_events_url": "https://api.github.com/users/mitchellhamilton/received_events", 457 | "type": "User", 458 | "site_admin": false 459 | }, 460 | "installation": { 461 | "id": 2462428, 462 | "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMjQ2MjQyOA==" 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "commonjs", 5 | "noEmit": true, 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "skipLibCheck": true, 10 | "lib": ["dom", "dom.iterable", "esnext"], 11 | "allowJs": false, 12 | "incremental": false, 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve" 16 | }, 17 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 18 | "exclude": ["node_modules"] 19 | } 20 | --------------------------------------------------------------------------------