Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions .github/workflows/publish-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,19 @@ jobs:
name: Build
env:
NODE_OPTIONS: --max-old-space-size=4096
- run: npx wrangler versions upload
name: Deploy to Cloudflare Workers
- name: Deploy to Cloudflare Workers
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
WRANGLER_OUTPUT_FILE_PATH: wrangler-logs.json
- name: Post preview URL on PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR=$(gh pr list --head ${{ github.ref_name }} --limit 1 --json number --jq '.[].number')

if [ -n "$PR" ]; then
URL=$(cat wrangler-logs.json | jq -r 'select(.type=="version-upload") | .preview_url')
SHORT_SHA=$(git rev-parse --short=8 HEAD)
BRANCH_SLUG=$(git rev-parse --abbrev-ref HEAD | iconv -c -t ascii//TRANSLIT | sed -E 's/[~^]+//g' | sed -E 's/[^a-zA-Z0-9]+/-/g' | sed -E 's/^-+|-+$//g' | tr A-Z a-z)

if [ -n "$URL" ]; then
BODY="**Preview URL:** $URL"
gh pr comment "$PR" --edit-last --body "$BODY" || gh pr comment "$PR" --body "$BODY"
fi
fi
npx wrangler deploy --dispatch-namespace preview-deployments --name $SHORT_SHA
npx wrangler deploy --dispatch-namespace preview-deployments --name $BRANCH_SLUG
- name: Post preview URL on PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx tsx bin/post-preview-url-comment/index.ts
- uses: actions/cache/save@v4
if: always()
with:
Expand Down
27 changes: 0 additions & 27 deletions .github/workflows/show-changed-files.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export const GITHUB_ACTIONS_BOT_ID = 41898282;
export const DOCS_BASE_URL = "https://developers.cloudflare.com";
export const CONTENT_BASE_PATH = "src/content";
export const EXISTING_COMMENT_SUBSTRING = "| Original Link | Updated Link |";
export const PREVIEW_URL_REGEX = /^\*\*Preview URL:\*\* (.*)$/m;
75 changes: 75 additions & 0 deletions bin/post-preview-url-comment/index.node.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { describe, expect, test } from "vitest";
import { DOCS_BASE_URL, PREVIEW_URL_REGEX } from "./constants";
import { filenameToPath, branchToSubdomain } from "./util";

describe("PREVIEW_URL_REGEX", () => {
test("no changed files", () => {
const comment =
"**Preview URL:** https://e9c79bc3.preview.developers.cloudflare.com\n**Preview Branch URL:** https://kian-pcx-15803.preview.developers.cloudflare.com";

expect(PREVIEW_URL_REGEX.test(comment)).toBe(true);
});

test("changed files", () => {
const comment =
"**Preview URL:** https://e9c79bc3.preview.developers.cloudflare.com\n**Preview Branch URL:** https://kian-pcx-15803.preview.developers.cloudflare.com\n\n**Files with changes (up to 15)**\n\n| Original Link | Updated Link |\n| --- | --- |\n| [https://developers.cloudflare.com/workers/get-started/guide/](https://developers.cloudflare.com/workers/get-started/guide/) | [https://kian-pcx-15803.preview.developers.cloudflare.com/workers/get-started/guide/](https://kian-pcx-15803.preview.developers.cloudflare.com/workers/get-started/guide/) |";

expect(PREVIEW_URL_REGEX.test(comment)).toBe(true);
});

test("empty", () => {
expect(PREVIEW_URL_REGEX.test("")).toBe(false);
});
});

describe("branchToSubdomain", () => {
test("slash", () => {
expect(branchToSubdomain("kian/pcx-15803")).toEqual("kian-pcx-15803");
});

test("normal", () => {
expect(branchToSubdomain("pcx-15803")).toEqual("pcx-15803");
});

test("capitalisation", () => {
expect(branchToSubdomain("PCX-15803")).toEqual("pcx-15803");
});
});

describe("filenameToPath", () => {
test("index", () => {
expect(filenameToPath("src/content/docs/workers/index.mdx")).toEqual(
"workers/",
);
});

test("index base", () => {
expect(
`${DOCS_BASE_URL}/${filenameToPath("src/content/docs/workers/index.mdx")}`,
).toEqual("https://developers.cloudflare.com/workers/");
});

test("folder", () => {
expect(
filenameToPath("src/content/docs/workers/get-started/cli.mdx"),
).toEqual("workers/get-started/cli/");
});

test("1.1.1.1", () => {
expect(filenameToPath("src/content/docs/1111/index.mdx")).toEqual(
"1.1.1.1/",
);
});

test("changelog", () => {
expect(
filenameToPath("src/content/changelogs-next/2025-02-05-title.mdx"),
).toEqual("changelog/2025-02-05-title/");
});

test("changelog base", () => {
expect(
`${DOCS_BASE_URL}/${filenameToPath("src/content/changelogs-next/2025-02-05-title.mdx")}`,
).toEqual("https://developers.cloudflare.com/changelog/2025-02-05-title/");
});
});
136 changes: 136 additions & 0 deletions bin/post-preview-url-comment/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import * as core from "@actions/core";
import * as github from "@actions/github";

import {
CONTENT_BASE_PATH,
DOCS_BASE_URL,
GITHUB_ACTIONS_BOT_ID,
PREVIEW_URL_REGEX,
} from "./constants";

import { filenameToPath, branchToSubdomain } from "./util";

async function run(): Promise<void> {
try {
if (!process.env.GITHUB_TOKEN) {
core.setFailed(`Could not find GITHUB_TOKEN in env`);
process.exit();
}

const octokit = github.getOctokit(process.env.GITHUB_TOKEN);
const ctx = github.context;
const branch = ctx.ref.replace("refs/heads/", "");

core.info(`Finding pull requests for ${ctx.ref}`);

const { data: pulls } = await octokit.rest.pulls.list({
...ctx.repo,
head: `${ctx.repo.owner}:${branch}`,
});

const pull_number = pulls.at(0)?.number;

if (!pull_number) {
core.setFailed(`Could not find pull requests for ${ctx.ref}`);
process.exit();
}

core.info(`Found ${pull_number}`);

const files = await octokit.paginate(octokit.rest.pulls.listFiles, {
...ctx.repo,
pull_number,
per_page: 100,
});

core.info(`Found ${files.length} changed files for ${pull_number}`);

const { data: comments } = await octokit.rest.issues.listComments({
...ctx.repo,
issue_number: pull_number,
per_page: 100,
});

const existingComment = comments.find(
(comment) =>
comment.user?.id === GITHUB_ACTIONS_BOT_ID &&
PREVIEW_URL_REGEX.test(comment.body ?? ""),
);

if (existingComment) {
core.info(`Found existing comment with ID ${existingComment.id}`);
} else {
core.info(`No existing comment found`);
}

const previewUrl = {
branch: `https://${branchToSubdomain(branch)}.preview.developers.cloudflare.com`,
commit: `https://${ctx.sha.slice(0, 8)}.preview.developers.cloudflare.com`,
};

core.info(
`Commit URL: ${previewUrl.commit}\nBranch URL: ${previewUrl.branch}`,
);

const changedFiles = files
.filter(
(file) =>
file.filename.endsWith(".mdx") &&
(file.filename.startsWith(`${CONTENT_BASE_PATH}/docs/`) ||
file.filename.startsWith(`${CONTENT_BASE_PATH}/changelogs-next/`)),
)
.sort((a, b) => b.changes - a.changes)
.slice(0, 15) // Limit to 15 entries
.map(({ filename }) => {
const original = `${DOCS_BASE_URL}/${filenameToPath(filename)}`;
const preview = `${previewUrl.branch}/${filenameToPath(filename)}`;

core.info(
`Filename: ${filename}\nOriginal: ${original}\nPreview: ${preview}`,
);

return { original, preview };
});

let comment = `**Preview URL:** ${previewUrl.commit}\n**Preview Branch URL:** ${previewUrl.branch}`;
if (changedFiles.length !== 0) {
core.info(`Found ${changedFiles.length} after filtering paths`);

comment = comment.concat(
`\n\n**Files with changes (up to 15)**\n\n| Original Link | Updated Link |\n| --- | --- |\n${changedFiles
.map(
(file) =>
`| [${file.original}](${file.original}) | [${file.preview}](${file.preview}) |`,
)
.join("\n")}`,
);
}

if (existingComment) {
core.info(
`Updating ${existingComment.id} with ${JSON.stringify(comment)}`,
);
await octokit.rest.issues.updateComment({
owner: ctx.repo.owner,
repo: ctx.repo.repo,
comment_id: existingComment.id,
body: comment,
});
} else {
core.info(`Creating new comment with ${JSON.stringify(comment)}`);
await octokit.rest.issues.createComment({
owner: ctx.repo.owner,
repo: ctx.repo.repo,
issue_number: pull_number,
body: comment,
});
}
} catch (error) {
if (error instanceof Error) {
core.setFailed(error.message);
}
process.exit();
}
}

run();
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { slug } from "github-slugger";

import { execSync } from "node:child_process";
import { CONTENT_BASE_PATH } from "./constants";

export const filenameToPath = (filename: string) => {
Expand Down Expand Up @@ -29,3 +29,10 @@ export const filenameToPath = (filename: string) => {
.replace(/\/index$/, "")
.concat("/");
};

export const branchToSubdomain = (branch: string) => {
return execSync(
`echo "${branch}" | iconv -c -t ascii//TRANSLIT | sed -E 's/[~^]+//g' | sed -E 's/[^a-zA-Z0-9]+/-/g' | sed -E 's/^-+|-+$//g' | tr A-Z a-z`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

errm. Ideally we have this in code and use it for both CI and this haha

{ encoding: "utf-8" },
).trim();
};
52 changes: 0 additions & 52 deletions bin/show-changed-files/index.node.test.ts

This file was deleted.

Loading
Loading