Skip to content

Commit

Permalink
update to latest upload-artifact, apply fixes on PR head
Browse files Browse the repository at this point in the history
  • Loading branch information
mhils committed Jun 23, 2024
1 parent 91a40b5 commit 5d15622
Show file tree
Hide file tree
Showing 9 changed files with 839 additions and 123 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/autofix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: autofix.ci # needed to securely identify the workflow

on:
pull_request:
push:
branches: [ "main" ]
permissions:
contents: read

jobs:
autofix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build

- uses: autofix-ci/action@d3e591514b99d0fca6779455ff8338516663f7cc
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
See https://github.com/autofix-ci/action/releases.
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ branding:
color: 'green'
runs:
using: 'node20'
main: 'index.js'
main: 'index.dist.js'
inputs:
fail-fast:
description: 'Cancel all other workflows associated with a commit when fixing it.'
Expand Down
252 changes: 252 additions & 0 deletions index.dist.js

Large diffs are not rendered by default.

121 changes: 0 additions & 121 deletions index.js

This file was deleted.

123 changes: 123 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import {DefaultArtifactClient} from '@actions/artifact'
import {getInput, isDebug, setFailed, setOutput} from "@actions/core";
import {exec, getExecOutput} from "@actions/exec";
import {HttpClient} from "@actions/http-client";
import {readFile, rm, writeFile} from "fs/promises";


async function main() {
setOutput('autofix_started', false);

const event = JSON.parse(
await readFile(process.env.GITHUB_EVENT_PATH, {encoding: 'utf8'})
);
if (isDebug()) {
console.log(event);
}

if (process.env.GITHUB_WORKFLOW !== "autofix.ci") {
throw `For security reasons, the workflow in which the autofix.ci action is used must be named "autofix.ci".`;
}

await exec("git", ["reset"]);

await exec("git", ["-c", "core.fileMode=false", "add", "--all"]);

// Git consistently uses unix-style paths, so we do not need to worry about path conversions.
let {stdout} = await getExecOutput("git", ["diff", "--name-only", "--staged", "--no-renames"])
if (stdout === "") {
console.log("Nothing to do! ✨");
return;
}
let changes = stdout.trim().split("\n");
// UX: Already check here if we have forbidden files.
// This is truly enforced on the server, but this way we can give a better error message.
if (changes.some((path) => path.includes(".github"))) {
throw "The autofix.ci action is not allowed to modify the .github directory.";
}
console.log(`Need to update ${changes.length} files.`);

// For pull requests, we need to rebase the changes onto the PR head,
// see https://github.com/autofix-ci/action/issues/12.
if (event.pull_request) {
// Create a commit
await exec("git", ["commit", "-m", "autofix"]);
let {stdout: commit_hash} = await getExecOutput("git", ["rev-parse", "HEAD"])
// Fetch and check out PR head
await exec("git", ["fetch", "--depth=1", "origin", `+refs/pull/${event.pull_request.number}/head`]);
await exec("git", ["checkout", "--force", "FETCH_HEAD"]);
// Reapply fixes.
await exec("git", ["cherry-pick", "--no-edit", commit_hash]);
}

const fileChanges = {
additions: [],
deletions: []
};
await Promise.all(changes.map((async (filename) => {
let buf: Buffer;
try {
buf = await readFile(filename);
} catch (e) {
fileChanges.deletions.push({path: filename})
return;
}
fileChanges.additions.push({
path: filename,
contents: buf.toString("base64")
});
})));
if (isDebug()) {
console.log(fileChanges);
}

const client = new DefaultArtifactClient();

const filename = "autofix.json";
try {
await writeFile(filename, JSON.stringify({
version: 1,
changes: fileChanges,
failFast: getInput("fail-fast") === "true",
comment: getInput("comment") || undefined,
commitMessage: getInput("commit-message") || undefined,
}));
await client.uploadArtifact("autofix.ci", [filename], ".", {
retentionDays: 1
});
} finally {
await rm(filename, {maxRetries: 3});
}

let url = (
"https://api.autofix.ci/fix" +
"?owner=" + encodeURIComponent(event.repository.owner.login) +
"&repo=" + encodeURIComponent(event.repository.name)
)
if (event.pull_request) {
url += "&pull=" + encodeURIComponent(event.pull_request.number);
} else {
url += "&branch=" + encodeURIComponent(event.ref.replace(/^refs\/heads\//, ""));
}

const http = new HttpClient("autofix-action/v2");
const resp = await http.post(url, null);
const body = await resp.readBody();
if (resp.message.statusCode === 200) {
setFailed("✅ Autofix task started.");
setOutput('autofix_started', true);
} else {
console.log(resp.message.statusCode, body);
setFailed(body);
}
// show the user what needs to be changed.
await exec("git", ["diff", "--staged"]);
}

(async function run() {
try {
await main();
} catch (error) {
setFailed(String(error).replace(/^Error: /, ""));
}
})();
Loading

0 comments on commit 5d15622

Please sign in to comment.