@@ -0,0 +1,53 @@
+# Generated from xtask::workflows::autofix_pr
+# Rebuild with `cargo xtask workflows`.
+name: autofix_pr
+run-name: 'autofix PR #${{ inputs.pr_number }}'
+on:
+ workflow_dispatch:
+ inputs:
+ pr_number:
+ description: pr_number
+ required: true
+ type: string
+jobs:
+ run_autofix:
+ runs-on: namespace-profile-2x4-ubuntu-2404
+ steps:
+ - id: get-app-token
+ name: autofix_pr::run_autofix::authenticate_as_zippy
+ uses: actions/create-github-app-token@bef1eaf1c0ac2b148ee2a0a74c65fbe6db0631f1
+ with:
+ app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}
+ private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }}
+ - name: steps::checkout_repo_with_token
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+ with:
+ clean: false
+ token: ${{ steps.get-app-token.outputs.token }}
+ - name: autofix_pr::run_autofix::checkout_pr
+ run: gh pr checkout ${{ inputs.pr_number }}
+ shell: bash -euxo pipefail {0}
+ env:
+ GITHUB_TOKEN: ${{ steps.get-app-token.outputs.token }}
+ - name: autofix_pr::run_autofix::run_cargo_fmt
+ run: cargo fmt --all
+ shell: bash -euxo pipefail {0}
+ - name: autofix_pr::run_autofix::run_clippy_fix
+ run: cargo clippy --workspace --release --all-targets --all-features --fix --allow-dirty --allow-staged
+ shell: bash -euxo pipefail {0}
+ - name: autofix_pr::run_autofix::commit_and_push
+ run: |
+ if git diff --quiet; then
+ echo "No changes to commit"
+ else
+ git add -A
+ git commit -m "Apply cargo fmt and clippy --fix"
+ git push
+ fi
+ shell: bash -euxo pipefail {0}
+ env:
+ GIT_COMMITTER_NAME: Zed Zippy
+ GIT_COMMITTER_EMAIL: hi@zed.dev
+ GIT_AUTHOR_NAME: Zed Zippy
+ GIT_AUTHOR_EMAIL: hi@zed.dev
+ GITHUB_TOKEN: ${{ steps.get-app-token.outputs.token }}
@@ -5,6 +5,7 @@ use std::fs;
use std::path::{Path, PathBuf};
mod after_release;
+mod autofix_pr;
mod cherry_pick;
mod compare_perf;
mod danger;
@@ -111,6 +112,7 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> {
WorkflowFile::zed(run_tests::run_tests),
WorkflowFile::zed(release::release),
WorkflowFile::zed(cherry_pick::cherry_pick),
+ WorkflowFile::zed(autofix_pr::autofix_pr),
WorkflowFile::zed(compare_perf::compare_perf),
WorkflowFile::zed(run_agent_evals::run_unit_evals),
WorkflowFile::zed(run_agent_evals::run_cron_unit_evals),
@@ -0,0 +1,77 @@
+use gh_workflow::*;
+
+use crate::tasks::workflows::{
+ runners,
+ steps::{self, NamedJob, named},
+ vars::{self, StepOutput, WorkflowInput},
+};
+
+pub fn autofix_pr() -> Workflow {
+ let pr_number = WorkflowInput::string("pr_number", None);
+ let autofix = run_autofix(&pr_number);
+ named::workflow()
+ .run_name(format!("autofix PR #{pr_number}"))
+ .on(Event::default().workflow_dispatch(
+ WorkflowDispatch::default().add_input(pr_number.name, pr_number.input()),
+ ))
+ .add_job(autofix.name, autofix.job)
+}
+
+fn run_autofix(pr_number: &WorkflowInput) -> NamedJob {
+ fn authenticate_as_zippy() -> (Step<Use>, StepOutput) {
+ let step = named::uses(
+ "actions",
+ "create-github-app-token",
+ "bef1eaf1c0ac2b148ee2a0a74c65fbe6db0631f1",
+ )
+ .add_with(("app-id", vars::ZED_ZIPPY_APP_ID))
+ .add_with(("private-key", vars::ZED_ZIPPY_APP_PRIVATE_KEY))
+ .id("get-app-token");
+ let output = StepOutput::new(&step, "token");
+ (step, output)
+ }
+
+ fn checkout_pr(pr_number: &WorkflowInput, token: &StepOutput) -> Step<Run> {
+ named::bash(&format!("gh pr checkout {pr_number}")).add_env(("GITHUB_TOKEN", token))
+ }
+
+ fn run_cargo_fmt() -> Step<Run> {
+ named::bash("cargo fmt --all")
+ }
+
+ fn run_clippy_fix() -> Step<Run> {
+ named::bash(
+ "cargo clippy --workspace --release --all-targets --all-features --fix --allow-dirty --allow-staged",
+ )
+ }
+
+ fn commit_and_push(token: &StepOutput) -> Step<Run> {
+ named::bash(indoc::indoc! {r#"
+ if git diff --quiet; then
+ echo "No changes to commit"
+ else
+ git add -A
+ git commit -m "Apply cargo fmt and clippy --fix"
+ git push
+ fi
+ "#})
+ .add_env(("GIT_COMMITTER_NAME", "Zed Zippy"))
+ .add_env(("GIT_COMMITTER_EMAIL", "hi@zed.dev"))
+ .add_env(("GIT_AUTHOR_NAME", "Zed Zippy"))
+ .add_env(("GIT_AUTHOR_EMAIL", "hi@zed.dev"))
+ .add_env(("GITHUB_TOKEN", token))
+ }
+
+ let (authenticate, token) = authenticate_as_zippy();
+
+ named::job(
+ Job::default()
+ .runs_on(runners::LINUX_SMALL)
+ .add_step(authenticate)
+ .add_step(steps::checkout_repo_with_token(&token))
+ .add_step(checkout_pr(pr_number, &token))
+ .add_step(run_cargo_fmt())
+ .add_step(run_clippy_fix())
+ .add_step(commit_and_push(&token)),
+ )
+}
@@ -1,6 +1,6 @@
use gh_workflow::*;
-use crate::tasks::workflows::{runners::Platform, vars};
+use crate::tasks::workflows::{runners::Platform, vars, vars::StepOutput};
pub const BASH_SHELL: &str = "bash -euxo pipefail {0}";
// https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idstepsshell
@@ -17,6 +17,16 @@ pub fn checkout_repo() -> Step<Use> {
.add_with(("clean", false))
}
+pub fn checkout_repo_with_token(token: &StepOutput) -> Step<Use> {
+ named::uses(
+ "actions",
+ "checkout",
+ "11bd71901bbe5b1630ceea73d27597364c9af683", // v4
+ )
+ .add_with(("clean", false))
+ .add_with(("token", token.to_string()))
+}
+
pub fn setup_pnpm() -> Step<Use> {
named::uses(
"pnpm",