mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
141 lines
4.1 KiB
JavaScript
141 lines
4.1 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
// oxlint-disable no-console
|
|
|
|
/**
|
|
* Get changed files from GitHub events (pull request or push).
|
|
* This module provides a reusable function for detecting changed files.
|
|
*/
|
|
|
|
const https = require("https");
|
|
const process = require("process");
|
|
|
|
/**
|
|
* Make a GitHub API request
|
|
* @param {string} path - API path
|
|
* @returns {Promise<any>} API response
|
|
*/
|
|
function githubApi(path) {
|
|
return new Promise((resolve, reject) => {
|
|
const options = {
|
|
hostname: "api.github.com",
|
|
path,
|
|
headers: {
|
|
"User-Agent": "oxc-changed-files",
|
|
Accept: "application/vnd.github.v3+json",
|
|
},
|
|
};
|
|
|
|
// Add authorization if token is available
|
|
const token = process.env.GITHUB_TOKEN;
|
|
if (token) {
|
|
options.headers["Authorization"] = `token ${token}`;
|
|
}
|
|
|
|
https
|
|
.get(options, (res) => {
|
|
let data = "";
|
|
res.on("data", (chunk) => (data += chunk));
|
|
res.on("end", () => {
|
|
if (res.statusCode === 200) {
|
|
resolve(JSON.parse(data));
|
|
} else {
|
|
reject(new Error(`GitHub API error: ${res.statusCode} ${data}`));
|
|
}
|
|
});
|
|
})
|
|
.on("error", reject);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get all changed files for a PR, paginating through all pages
|
|
* @param {string} repository - Repository name (owner/repo)
|
|
* @param {string} prNumber - Pull request number
|
|
* @returns {Promise<string[]>} Array of changed file paths
|
|
*/
|
|
async function getPrChangedFiles(repository, prNumber) {
|
|
const perPage = 100;
|
|
const files = [];
|
|
let page = 1;
|
|
let prFiles;
|
|
do {
|
|
// oxlint-disable-next-line no-await-in-loop -- sequential pagination requires await in loop
|
|
prFiles = await githubApi(
|
|
`/repos/${repository}/pulls/${prNumber}/files?per_page=${perPage}&page=${page}`,
|
|
);
|
|
for (const f of prFiles) {
|
|
files.push(f.filename);
|
|
}
|
|
page++;
|
|
} while (prFiles.length >= perPage);
|
|
return files;
|
|
}
|
|
|
|
/**
|
|
* Get changed files based on the GitHub event type
|
|
* @returns {Promise<string[] | null>} Array of changed file paths, or null to signal "run all"
|
|
*/
|
|
async function getChangedFiles() {
|
|
const eventName = process.env.GITHUB_EVENT_NAME;
|
|
const repository = process.env.GITHUB_REPOSITORY;
|
|
const sha = process.env.GITHUB_SHA;
|
|
const prNumber = process.env.GITHUB_PR_NUMBER;
|
|
const ref = process.env.GITHUB_REF;
|
|
|
|
console.error(`Event: ${eventName}`);
|
|
console.error(`Repository: ${repository}`);
|
|
console.error(`SHA: ${sha}`);
|
|
console.error(`Ref: ${ref}`);
|
|
|
|
if (eventName === "workflow_dispatch") {
|
|
console.error("Manual trigger - returning null (run all)");
|
|
return null; // Signal to run all
|
|
}
|
|
|
|
let files = [];
|
|
|
|
try {
|
|
if (eventName === "pull_request" && prNumber) {
|
|
// For PR, use GitHub API to get changed files (paginated)
|
|
console.error(`Getting changed files for PR #${prNumber}`);
|
|
files = await getPrChangedFiles(repository, prNumber);
|
|
} else if (sha && repository) {
|
|
// For push to main, get the commit and compare with parent
|
|
console.error(`Getting changed files for commit ${sha}`);
|
|
const commit = await githubApi(`/repos/${repository}/commits/${sha}`);
|
|
files = commit.files ? commit.files.map((f) => f.filename) : [];
|
|
} else {
|
|
// No valid parameters for API calls
|
|
console.error("Error: Missing required environment variables for GitHub API");
|
|
console.error("Returning null (run all) as fallback");
|
|
return null; // Signal to run all
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error getting changed files via API: ${error.message}`);
|
|
console.error("Returning null (run all) as fallback");
|
|
return null; // Signal to run all
|
|
}
|
|
|
|
console.error(`Changed files (${files.length}):`);
|
|
files.forEach((f) => console.error(` - ${f}`));
|
|
|
|
return files;
|
|
}
|
|
|
|
module.exports = { getChangedFiles };
|
|
|
|
// If run directly as a script, output changed files as JSON
|
|
if (require.main === module) {
|
|
getChangedFiles()
|
|
.then((files) => {
|
|
console.log(JSON.stringify(files));
|
|
process.exit(0);
|
|
})
|
|
.catch((error) => {
|
|
console.error("Error:", error);
|
|
console.log(JSON.stringify(null));
|
|
process.exit(1);
|
|
});
|
|
}
|