@goodfellow-cms/github 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -134,19 +134,19 @@ export declare class GitHubBackend implements GitBackend {
134
134
  readAt(path: string, revision: string): Promise<string | undefined>;
135
135
  changedPaths(from: string, to: string): Promise<string[]>;
136
136
  /**
137
- * Reads the deployment GitHub Pages or Vercel created for a commit, or what
138
- * Cloudflare Pages reports on it, and for GitHub Actions, the workflow run
137
+ * Reads the deployment GitHub Pages, Vercel or Netlify created for a commit,
138
+ * or what Cloudflare Pages or Netlify reports on it, and for GitHub Actions, the workflow run
139
139
  * that builds it: a build that fails never creates a deployment. Before any
140
140
  * exists, the site counts as building if it has ever been deployed, or if
141
141
  * Cloudflare reported on the commit before.
142
142
  */
143
143
  deployStatus(revision: string): Promise<DeployStatus>;
144
144
  /**
145
- * What Cloudflare Pages reports on a commit: a check run of its GitHub App,
146
- * or a commit status, which fine-grained tokens can read where check runs
147
- * need a GitHub App's permission. `undefined` if it reported nothing.
145
+ * What Cloudflare Pages or Netlify reports on a commit: a check run of its
146
+ * GitHub App, or a commit status, which fine-grained tokens can read where
147
+ * check runs need a GitHub App's permission. `undefined` if it reported nothing.
148
148
  */
149
- private cloudflareBuild;
149
+ private hostBuild;
150
150
  /** The commit a commit was made on top of, if the token can see it. */
151
151
  private parentOf;
152
152
  /** The site's deploy workflow run for a commit, or `undefined` if there's none or the token can't see Actions. */
package/dist/index.js CHANGED
@@ -860,8 +860,14 @@ function githubCodeUpdates(options) {
860
860
  }
861
861
  //#endregion
862
862
  //#region src/backend.ts
863
- /** Cloudflare Pages' check runs (its GitHub App is "Cloudflare Workers and Pages") and commit statuses. */
864
- const CLOUDFLARE = /cloudflare/i;
863
+ /**
864
+ * The check runs and commit statuses of hosts that build the site themselves
865
+ * and report to GitHub: Cloudflare Pages (its GitHub App is "Cloudflare Workers
866
+ * and Pages") and Netlify's deploys (`netlify/<site>/deploy…`), but not its
867
+ * other checks, such as "Header rules", which finish before the deploy does.
868
+ * Netlify's GitHub App also creates a deployment, which `deployStatus()` reads first.
869
+ */
870
+ const HOST_BUILDS = /cloudflare|netlify\/\S+\/deploy/i;
865
871
  /** How many files one GraphQL request reads. */
866
872
  const GRAPHQL_BATCH = 100;
867
873
  /** The most files GitHub's compare lists. */
@@ -1301,8 +1307,8 @@ var GitHubBackend = class GitHubBackend {
1301
1307
  return [...new Set(files.flatMap((file) => [file.filename, file.previous_filename ?? []].flat()))];
1302
1308
  }
1303
1309
  /**
1304
- * Reads the deployment GitHub Pages or Vercel created for a commit, or what
1305
- * Cloudflare Pages reports on it, and for GitHub Actions, the workflow run
1310
+ * Reads the deployment GitHub Pages, Vercel or Netlify created for a commit,
1311
+ * or what Cloudflare Pages or Netlify reports on it, and for GitHub Actions, the workflow run
1306
1312
  * that builds it: a build that fails never creates a deployment. Before any
1307
1313
  * exists, the site counts as building if it has ever been deployed, or if
1308
1314
  * Cloudflare reported on the commit before.
@@ -1334,8 +1340,8 @@ var GitHubBackend = class GitHubBackend {
1334
1340
  };
1335
1341
  }
1336
1342
  }
1337
- const cloudflare = await this.cloudflareBuild(revision);
1338
- if (cloudflare) return cloudflare;
1343
+ const hosted = await this.hostBuild(revision);
1344
+ if (hosted) return hosted;
1339
1345
  const run = await this.workflowRun(revision);
1340
1346
  if (run?.status === "completed" && run.conclusion === "cancelled") {
1341
1347
  const head = await this.head();
@@ -1352,22 +1358,22 @@ var GitHubBackend = class GitHubBackend {
1352
1358
  };
1353
1359
  if ((await githubJson(this.api, `/repos/${this.repo}/deployments?per_page=1`)).length > 0) return { state: "building" };
1354
1360
  const parent = await this.parentOf(revision);
1355
- return { state: parent && await this.cloudflareBuild(parent) ? "building" : "unknown" };
1361
+ return { state: parent && await this.hostBuild(parent) ? "building" : "unknown" };
1356
1362
  } catch (error) {
1357
1363
  if (error instanceof GitApiError) return { state: "unknown" };
1358
1364
  throw error;
1359
1365
  }
1360
1366
  }
1361
1367
  /**
1362
- * What Cloudflare Pages reports on a commit: a check run of its GitHub App,
1363
- * or a commit status, which fine-grained tokens can read where check runs
1364
- * need a GitHub App's permission. `undefined` if it reported nothing.
1368
+ * What Cloudflare Pages or Netlify reports on a commit: a check run of its
1369
+ * GitHub App, or a commit status, which fine-grained tokens can read where
1370
+ * check runs need a GitHub App's permission. `undefined` if it reported nothing.
1365
1371
  */
1366
- async cloudflareBuild(revision) {
1372
+ async hostBuild(revision) {
1367
1373
  const checks = await githubRequest(this.api, `/repos/${this.repo}/commits/${revision}/check-runs?per_page=50`, { allow: [403, 404] });
1368
1374
  if (checks.ok) {
1369
1375
  const { check_runs: found = [] } = await checks.json();
1370
- const run = found.find((candidate) => CLOUDFLARE.test(`${candidate.app?.slug ?? ""} ${candidate.name}`));
1376
+ const run = found.find((candidate) => HOST_BUILDS.test(`${candidate.app?.slug ?? ""} ${candidate.name}`));
1371
1377
  if (run) {
1372
1378
  const detailsUrl = run.details_url ?? run.html_url ?? void 0;
1373
1379
  if (run.status !== "completed") return {
@@ -1390,7 +1396,7 @@ var GitHubBackend = class GitHubBackend {
1390
1396
  }
1391
1397
  const statuses = await githubRequest(this.api, `/repos/${this.repo}/commits/${revision}/statuses?per_page=50`, { allow: [403, 404] });
1392
1398
  if (!statuses.ok) return void 0;
1393
- const status = (await statuses.json()).find((candidate) => CLOUDFLARE.test(candidate.context));
1399
+ const status = (await statuses.json()).find((candidate) => HOST_BUILDS.test(candidate.context));
1394
1400
  if (!status) return void 0;
1395
1401
  const detailsUrl = status.target_url ?? void 0;
1396
1402
  if (status.state === "success") return {
package/dist/testing.d.ts CHANGED
@@ -87,6 +87,14 @@ export interface FakeGitHubOptions {
87
87
  afterChecks: number;
88
88
  report?: "check-runs" | "statuses";
89
89
  };
90
+ /**
91
+ * Simulates Netlify, as `cloudflare` does Cloudflare Pages: its GitHub App's
92
+ * "Header rules" check run, which finishes at once, and a commit status for
93
+ * the deploy, which reports success after being checked this many times.
94
+ */
95
+ netlify?: {
96
+ afterChecks: number;
97
+ };
90
98
  /** Answers 403 to reading check runs, as GitHub does for fine-grained tokens, which can't have the permission. */
91
99
  checkRunsForbidden?: boolean;
92
100
  /** Organizations the users belong to, which new repositories can be created in. */
package/dist/testing.js CHANGED
@@ -623,7 +623,7 @@ function fakeGitHub(options) {
623
623
  }
624
624
  }
625
625
  function deploy(sha) {
626
- if (options.cloudflare) cloudflareBuilds.set(sha, { checks: 0 });
626
+ if (options.cloudflare || options.netlify) cloudflareBuilds.set(sha, { checks: 0 });
627
627
  if (options.deployAfterChecks === void 0) return;
628
628
  deployments.unshift({
629
629
  id: nextDeployment++,
@@ -638,7 +638,7 @@ function fakeGitHub(options) {
638
638
  if (!build) return void 0;
639
639
  build.checks += 1;
640
640
  if (build.failed) return "failure";
641
- return build.checks > (options.cloudflare?.afterChecks ?? 0) ? "success" : "building";
641
+ return build.checks > (options.cloudflare?.afterChecks ?? options.netlify?.afterChecks ?? 0) ? "success" : "building";
642
642
  }
643
643
  function failCloudflare(sha) {
644
644
  cloudflareBuilds.set(sha, {
@@ -1261,6 +1261,19 @@ function fakeGitHub(options) {
1261
1261
  const checkRunsSha = rest.match(/^\/commits\/([0-9a-f]{40})\/check-runs$/)?.[1];
1262
1262
  if (checkRunsSha) {
1263
1263
  if (options.checkRunsForbidden) return json({ message: "Resource not accessible by personal access token" }, 403);
1264
+ if (options.netlify) {
1265
+ const known = cloudflareBuilds.has(checkRunsSha);
1266
+ return json({
1267
+ total_count: known ? 1 : 0,
1268
+ check_runs: known ? [{
1269
+ id: 1,
1270
+ name: "Header rules - parish",
1271
+ app: { slug: "netlify" },
1272
+ status: "completed",
1273
+ conclusion: "neutral"
1274
+ }] : []
1275
+ });
1276
+ }
1264
1277
  const state = options.cloudflare?.report === "statuses" ? void 0 : cloudflareState(checkRunsSha);
1265
1278
  const runsFound = state ? [{
1266
1279
  id: 1,
@@ -1278,6 +1291,15 @@ function fakeGitHub(options) {
1278
1291
  }
1279
1292
  const statusesSha = rest.match(/^\/commits\/([0-9a-f]{40})\/statuses$/)?.[1];
1280
1293
  if (statusesSha) {
1294
+ if (options.netlify) {
1295
+ const deploy = cloudflareState(statusesSha);
1296
+ return json(deploy ? [{
1297
+ context: "netlify/parish/deploy-preview",
1298
+ state: deploy === "building" ? "pending" : deploy,
1299
+ target_url: `https://app.netlify.com/sites/parish/deploys/${statusesSha}`,
1300
+ description: deploy === "failure" ? "Deploy failed" : "Deploy is ready!"
1301
+ }] : []);
1302
+ }
1281
1303
  const state = options.cloudflare?.report === "statuses" ? cloudflareState(statusesSha) : void 0;
1282
1304
  return json(state ? [{
1283
1305
  context: "Cloudflare Pages",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@goodfellow-cms/github",
3
- "version": "0.8.0",
4
- "description": "Edit a Goodfellow site stored on GitHub, straight from the browser.",
3
+ "version": "0.9.0",
4
+ "description": "Edit a Goodfellow CMS site stored on GitHub, straight from the browser.",
5
5
  "keywords": [
6
6
  "goodfellow",
7
7
  "cms",
@@ -12,6 +12,10 @@
12
12
  ],
13
13
  "homepage": "https://goodfellow-cms.github.io/goodfellow-cms/docs/hosts",
14
14
  "bugs": "https://github.com/goodfellow-cms/goodfellow-cms/issues",
15
+ "funding": {
16
+ "type": "github",
17
+ "url": "https://github.com/sponsors/goodfellow-cms"
18
+ },
15
19
  "license": "MIT",
16
20
  "repository": {
17
21
  "type": "git",
@@ -35,7 +39,7 @@
35
39
  "dist"
36
40
  ],
37
41
  "dependencies": {
38
- "@goodfellow-cms/core": "0.8.0",
42
+ "@goodfellow-cms/core": "0.9.0",
39
43
  "@noble/ciphers": "2.4.0",
40
44
  "@noble/hashes": "2.4.0"
41
45
  },