Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: swc-project/swc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 016fe1416460f5fdfdbc18d5c922a8eb6ed625d7
Choose a base ref
...
head repository: swc-project/swc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 9fc089662e7fe7e85d89e5ce98ec43431d42973e
Choose a head ref
Loading
Showing 15,545 changed files with 1,269,604 additions and 1,495,144 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .github/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ body:
required: true
attributes:
label: Playground link (or link to the minimal reproduction)
description: "You can use [swc playground](https://play.swc.rs/) to create a reproduction link, then paste the link here. If your link is invalid, the issue will be closed automatically. Allowed domains are github.com,play.swc.rs,evanw.github.io,lightningcss.dev,play.rust-lang.org"
description: "You can use [swc playground](https://play.swc.rs/) to create a reproduction link, then paste the link here. If your link is invalid, the issue will be closed automatically. Allowed domains are github.com,gist.github.com,play.swc.rs,evanw.github.io,lightningcss.dev,play.rust-lang.org,stackblitz.com"
- type: textarea
id: swc-info
attributes:
24 changes: 24 additions & 0 deletions .github/actions/setup-node/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: "Configure Node.js"
description: "Sets Node.js up for CI"
inputs:
node-version:
description: "Node version to install"
required: false
default: "20"

runs:
using: "composite"
steps:
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: "yarn"

- name: Enable corepack
shell: bash
run: corepack enable

- name: Install dependencies
shell: bash
run: yarn
File renamed without changes.
16 changes: 16 additions & 0 deletions .github/bot/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "swc-bot",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"devDependencies": {
"@types/node": "^17.0.17",
"ts-node": "^10.5.0",
"typescript": "^4.5.5"
},
"dependencies": {
"@octokit/rest": "^18.12.0",
"yaml": "^1.10.2"
}
}
87 changes: 87 additions & 0 deletions .github/bot/src/auto-rebase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { getTitleOfLatestCommit } from "./util/git";
import { octokit } from "./util/octokit";

// We only auto-rebase if the latest commit message is one of
//
// - test(*)
// - chore:

const owner = "swc-project";
const repo = "swc";

function sleep(ms: number) {
return new Promise((r) => setTimeout(r, ms));
}

(async () => {
const latestCommitMessage = await getTitleOfLatestCommit();

console.log(`Latest commit message: ${latestCommitMessage}`);

if (!latestCommitMessage.startsWith("chore:")) {
console.log(
`Auto rebase script cannot work because the latest commit may require a version bump`
);
return;
}

const allPrs = await octokit.rest.pulls.list({
owner,
repo,
state: "open",
sort: "long-running",
direction: "desc",
});

const autoMergePrs = allPrs.data.filter((pr) => !!pr.auto_merge);

if (autoMergePrs.length === 0) {
console.log(`No PRs with auto-merge enabled`);
return;
}

for (const pr of autoMergePrs) {
try {
const baseBranch = await octokit.rest.repos.getBranch({
owner,
repo,
branch: pr.base.ref,
});
if (baseBranch.data.commit.sha === pr.base.sha) {
console.error(`PR #${pr.number} is already up-to-date`);
continue;
}

await octokit.rest.pulls.updateBranch({
owner,
repo,
pull_number: pr.number,
expected_head_sha: pr.head.sha,
});

console.log(`Updated PR ${pr.number} to merge upstream`);

await sleep(3000);

const review = await octokit.pulls.createReview({
owner,
repo,
pull_number: pr.number,
});
console.log(`Created a review on PR ${pr.number}`);

await octokit.pulls.submitReview({
owner,
repo,
pull_number: pr.number,
review_id: review.data.id,
event: "COMMENT",
body: "Automated review comment generated by auto-rebase script",
});

break;
} catch (e) {
console.error(`Failed to auto-rebase:`, e);
}
}
})();
44 changes: 44 additions & 0 deletions .github/bot/src/cargo/bump.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { exec } from "child_process";
import { getTitleOfLatestCommit } from "../util/git";
import { parsePrComments } from "./comment-parser";
import { promisify } from "util";

const execAsync = promisify(exec);

(async () => {
const latestCommitMessage = await getTitleOfLatestCommit();
console.log("Latest commit message:", latestCommitMessage);

const lParenIndex = latestCommitMessage.lastIndexOf("(#");

console.log(lParenIndex);

if (!latestCommitMessage.endsWith(")") || lParenIndex === -1) {
console.log(`This commit does not seems like a PR merge`);
process.exit(1);
return;
}

const prNumber = parseInt(
latestCommitMessage.substring(
lParenIndex + 2,
latestCommitMessage.length - 1
)
);

const actions = await parsePrComments(prNumber);

if (actions.length === 0) {
throw new Error("This commit does not require a bump commit");
}

for (const action of actions) {
console.log(action);

if (action.breaking) {
await execAsync(`cargo mono bump ${action.crate} --breaking`);
} else {
await execAsync(`cargo mono bump ${action.crate} -D`);
}
}
})();
58 changes: 58 additions & 0 deletions .github/bot/src/cargo/comment-parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { octokit } from "../util/octokit";
import YAML from "yaml";

const owner = "swc-project";
const repo = "swc";

export interface Action {
crate: string;
breaking: boolean;
}

export async function parsePrComments(prNumber: number): Promise<Action[]> {
const comments = await octokit.pulls.listReviews({
owner,
repo,
pull_number: prNumber,
});

const maintainers = await octokit.orgs.listPublicMembers({ org: owner });

return comments.data
.filter(
(c) => c.user && maintainers.data.find((m) => m.login === c.user?.login)
)
.map((c) => {
const idx = c.body.indexOf("swc-bump:");
if (idx === -1) {
return undefined;
}
return c.body.substring(idx);
})
.filter((text) => !!text)
.map((text) => text!)
.map((text) => YAML.parse(text))
.map((data) => data["swc-bump"])
.flatMap((data) => data)
.map((line) => {
if (typeof line !== "string") {
throw new Error(`Non-string data: ${line}`);
}
line = line.trim();

console.log(`Comment line: '${line}'`);

if (line.endsWith(" --breaking")) {
return {
crate: line.substring(0, line.length - " --breaking".length),
breaking: true,
};
}

return {
crate: line,
breaking: false,
};
})
.filter((l) => !!l);
}
15 changes: 15 additions & 0 deletions .github/bot/src/cargo/ensure-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getCurrentPrNumber } from "../util/octokit";
import { parsePrComments } from "./comment-parser";

(async () => {
const prNumber = getCurrentPrNumber();
console.log(`Checking PR #${prNumber}`);

const actions = await parsePrComments(prNumber);

if (actions.length === 0) {
throw new Error(
"PR does not have a review comment to parse. Please wait for a comment by @kdy1 to be added."
);
}
})();
31 changes: 31 additions & 0 deletions .github/bot/src/cargo/update-constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { exec } from "child_process";
import { getCommitSha } from "../util/git";
import * as fs from "fs";
import { promisify } from "util";
import * as path from "path";

const execAsync = promisify(exec);

const writeFile = promisify(fs.writeFile);

(async () => {
const sha = await getCommitSha();
const filePath = path.resolve(
__dirname,
"../../../../crates/swc_core/src/__diagnostics.rs"
);

await writeFile(
filePath,
`pub(crate) static PKG_SEMVER_FALLBACK: &str = include_str!(concat!(env!("OUT_DIR"), "/core_pkg_version.txt"));
pub(crate) static GIT_SHA: &str = "${sha}";`,
"utf-8"
);

await execAsync(`git config --global user.email "bot@swc.rs"`);
await execAsync(`git config --global user.name "SWC Bot"`);

// we won't push, it's only to avoid dirty check for the publish
await execAsync(`git add ${filePath}`);
await execAsync(`git commit -m 'build(swc/core): bump sha'`);
})();
56 changes: 56 additions & 0 deletions .github/bot/src/nightly-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// npx ts-node .github/bot/src/nightly-version.ts $version

import { octokit, owner, repo } from "./util/octokit";

function addZ(n: number) {
return n < 10 ? "0" + n : "" + n;
}

async function main() {
// Default to the core version in packages/core/package.json
const coreVersion = require("../../../packages/core/package.json").version;

const latest: string = process.argv[2] || coreVersion;

process.stderr.write(`Previous version: ${latest}\n`);

// Bump patch version

const [major, minor, patch] = latest.split("-")[0].split(".").map(Number);

// Nightly version after 1.2.3 is 1.2.4-nightly-20211020.1
// Nightly version after 1.2.3-nightly-20211020.1 is 1.2.3-nightly-20211020.2

const version = `${major}.${minor}.${patch}`;
// Nightly version

const date = new Date();

const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();

const datePart = `${year}${addZ(month)}${addZ(day)}`;

const base = `v${version}-nightly-${datePart}`;
let idx = 1;
let nightlyVersion = `${base}.${idx}`;

// Check if the nightly version already exists, using octokit and git tags

const { data: tagData } = await octokit.repos.listTags({
owner,
repo,
order: "desc",
});
const tags = tagData.map((tag) => tag.name);
while (tags.includes(nightlyVersion)) {
idx += 1;
nightlyVersion = `${base}.${idx}`;
}
process.stderr.write(`Nightly version: ${nightlyVersion}\n`);

process.stdout.write(`version=${nightlyVersion.substring(1)}\n`);
}

main();
31 changes: 31 additions & 0 deletions .github/bot/src/util/git.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { exec } from "child_process";
import { type Stream } from "stream";

async function streamToString(stream: Stream): Promise<string> {
const chunks: Buffer[] = [];
return new Promise((resolve, reject) => {
stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
stream.on("error", (err) => reject(err));
stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
});
}

export async function getTitleOfLatestCommit(): Promise<string> {
const { stdout } = await exec("git log -1 --pretty=%B");

const msg = await streamToString(stdout!);

const s = msg.trim();

return s.split("\n")[0];
}

export async function getCommitSha(): Promise<string> {
const { stdout } = exec("git rev-parse HEAD");

const msg = await streamToString(stdout!);

const s = msg.trim();

return s;
}
Loading