mirror of
https://github.com/zed-industries/zed.git
synced 2026-07-09 16:00:35 +00:00
extension_rollout: Add support for renaming and deleting files (#47329)
This is in preparation for removing one of the files in favor of having just one larger one (and perhaps renaming that in the future). Release Notes: - N/A
This commit is contained in:
parent
d42fe0bba4
commit
9ac94ce3e6
3 changed files with 235 additions and 17 deletions
90
.github/workflows/extension_workflow_rollout.yml
vendored
90
.github/workflows/extension_workflow_rollout.yml
vendored
|
|
@ -57,6 +57,7 @@ jobs:
|
|||
with:
|
||||
clean: false
|
||||
path: zed
|
||||
fetch-depth: '0'
|
||||
- name: steps::checkout_repo_with_token
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
|
|
@ -64,9 +65,61 @@ jobs:
|
|||
token: ${{ steps.generate-token.outputs.token }}
|
||||
repository: zed-extensions/${{ matrix.repo }}
|
||||
path: extension
|
||||
- name: extension_workflow_rollout::rollout_workflows_to_extension::copy_workflow_files
|
||||
- id: prev-tag
|
||||
name: extension_workflow_rollout::rollout_workflows_to_extension::get_previous_tag_commit
|
||||
run: |
|
||||
PREV_COMMIT=$(git rev-parse "extension-workflows^{commit}" 2>/dev/null || echo "")
|
||||
if [ -z "$PREV_COMMIT" ]; then
|
||||
echo "::error::No previous rollout tag 'extension-workflows' found. Cannot determine file changes."
|
||||
exit 1
|
||||
fi
|
||||
echo "Found previous rollout at commit: $PREV_COMMIT"
|
||||
echo "prev_commit=$PREV_COMMIT" >> "$GITHUB_OUTPUT"
|
||||
shell: bash -euxo pipefail {0}
|
||||
working-directory: zed
|
||||
- id: calc-changes
|
||||
name: extension_workflow_rollout::rollout_workflows_to_extension::get_removed_files
|
||||
run: |
|
||||
PREV_COMMIT="${{ steps.prev-tag.outputs.prev_commit }}"
|
||||
|
||||
if [ "${{ matrix.repo }}" = "workflows" ]; then
|
||||
WORKFLOW_DIR="extensions/workflows"
|
||||
else
|
||||
WORKFLOW_DIR="extensions/workflows/shared"
|
||||
fi
|
||||
|
||||
echo "Calculating changes from $PREV_COMMIT to HEAD for $WORKFLOW_DIR"
|
||||
|
||||
# Get deleted files (status D) and renamed files (status R - old name needs removal)
|
||||
# Using -M to detect renames, then extracting files that are gone from their original location
|
||||
REMOVED_FILES=$(git diff --name-status -M "$PREV_COMMIT" HEAD -- "$WORKFLOW_DIR" | \
|
||||
awk '/^D/ { print $2 } /^R/ { print $2 }' | \
|
||||
xargs -I{} basename {} 2>/dev/null | \
|
||||
tr '\n' ' ' || echo "")
|
||||
|
||||
REMOVED_FILES=$(echo "$REMOVED_FILES" | xargs)
|
||||
|
||||
echo "Files to remove: $REMOVED_FILES"
|
||||
echo "removed_files=$REMOVED_FILES" >> "$GITHUB_OUTPUT"
|
||||
shell: bash -euxo pipefail {0}
|
||||
working-directory: zed
|
||||
- name: extension_workflow_rollout::rollout_workflows_to_extension::sync_workflow_files
|
||||
run: |
|
||||
REMOVED_FILES="${{ steps.calc-changes.outputs.removed_files }}"
|
||||
|
||||
mkdir -p extension/.github/workflows
|
||||
cd extension/.github/workflows
|
||||
|
||||
if [ -n "$REMOVED_FILES" ]; then
|
||||
for file in $REMOVED_FILES; do
|
||||
if [ -f "$file" ]; then
|
||||
rm -f "$file"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
cd - > /dev/null
|
||||
|
||||
if [ "${{ matrix.repo }}" = "workflows" ]; then
|
||||
cp zed/extensions/workflows/*.yml extension/.github/workflows/
|
||||
else
|
||||
|
|
@ -107,3 +160,38 @@ jobs:
|
|||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
timeout-minutes: 10
|
||||
create_rollout_tag:
|
||||
needs:
|
||||
- rollout_workflows_to_extension
|
||||
runs-on: namespace-profile-2x4-ubuntu-2404
|
||||
steps:
|
||||
- id: generate-token
|
||||
name: extension_bump::generate_token
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}
|
||||
private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }}
|
||||
permission-contents: write
|
||||
- name: steps::checkout_repo_with_token
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
with:
|
||||
clean: false
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
fetch-depth: '0'
|
||||
- name: extension_workflow_rollout::create_rollout_tag::configure_git
|
||||
run: |
|
||||
git config user.name "zed-zippy[bot]"
|
||||
git config user.email "234243425+zed-zippy[bot]@users.noreply.github.com"
|
||||
shell: bash -euxo pipefail {0}
|
||||
- name: extension_workflow_rollout::create_rollout_tag::update_rollout_tag
|
||||
run: |
|
||||
if git rev-parse "extension-workflows" >/dev/null 2>&1; then
|
||||
git tag -d "extension-workflows"
|
||||
git push origin ":refs/tags/extension-workflows" || true
|
||||
fi
|
||||
|
||||
echo "Creating new tag 'extension-workflows' at $(git rev-parse --short HEAD)"
|
||||
git tag "extension-workflows"
|
||||
git push origin "extension-workflows"
|
||||
shell: bash -euxo pipefail {0}
|
||||
timeout-minutes: 1
|
||||
|
|
|
|||
|
|
@ -223,8 +223,10 @@ pub(crate) fn generate_token(
|
|||
permissions,
|
||||
}| {
|
||||
input
|
||||
.add("owner", owner)
|
||||
.add("repositories", repositories)
|
||||
.when_some(owner, |input, owner| input.add("owner", owner))
|
||||
.when_some(repositories, |input, repositories| {
|
||||
input.add("repositories", repositories)
|
||||
})
|
||||
.when_some(permissions, |input, permissions| {
|
||||
permissions
|
||||
.into_iter()
|
||||
|
|
@ -315,16 +317,24 @@ fn create_pull_request(new_version: StepOutput, generated_token: StepOutput) ->
|
|||
}
|
||||
|
||||
pub(crate) struct RepositoryTarget {
|
||||
owner: String,
|
||||
repositories: String,
|
||||
owner: Option<String>,
|
||||
repositories: Option<String>,
|
||||
permissions: Option<Vec<(String, Level)>>,
|
||||
}
|
||||
|
||||
impl RepositoryTarget {
|
||||
pub fn new<T: ToString>(owner: T, repositories: &[&str]) -> Self {
|
||||
Self {
|
||||
owner: owner.to_string(),
|
||||
repositories: repositories.join("\n"),
|
||||
owner: Some(owner.to_string()),
|
||||
repositories: Some(repositories.join("\n")),
|
||||
permissions: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current() -> Self {
|
||||
Self {
|
||||
owner: None,
|
||||
repositories: None,
|
||||
permissions: None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use gh_workflow::{
|
||||
Event, Expression, Job, Level, Run, Step, Strategy, Use, Workflow, WorkflowDispatch,
|
||||
};
|
||||
use indoc::formatdoc;
|
||||
use indoc::indoc;
|
||||
use serde_json::json;
|
||||
|
||||
|
|
@ -11,15 +12,19 @@ use crate::tasks::workflows::{
|
|||
vars::{self, StepOutput},
|
||||
};
|
||||
|
||||
const ROLLOUT_TAG_NAME: &str = "extension-workflows";
|
||||
|
||||
pub(crate) fn extension_workflow_rollout() -> Workflow {
|
||||
let fetch_repos = fetch_extension_repos();
|
||||
let rollout_workflows = rollout_workflows_to_extension(&fetch_repos);
|
||||
let create_tag = create_rollout_tag(&rollout_workflows);
|
||||
|
||||
named::workflow()
|
||||
.on(Event::default().workflow_dispatch(WorkflowDispatch::default()))
|
||||
.add_env(("CARGO_TERM_COLOR", "always"))
|
||||
.add_job(fetch_repos.name, fetch_repos.job)
|
||||
.add_job(rollout_workflows.name, rollout_workflows.job)
|
||||
.add_job(create_tag.name, create_tag.job)
|
||||
}
|
||||
|
||||
fn fetch_extension_repos() -> NamedJob {
|
||||
|
|
@ -28,7 +33,7 @@ fn fetch_extension_repos() -> NamedJob {
|
|||
.id("list-repos")
|
||||
.add_with((
|
||||
"script",
|
||||
indoc! {r#"
|
||||
indoc::indoc! {r#"
|
||||
const repos = await github.paginate(github.rest.repos.listForOrg, {
|
||||
org: 'zed-extensions',
|
||||
type: 'public',
|
||||
|
|
@ -66,6 +71,7 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
steps::checkout_repo()
|
||||
.name("checkout_zed_repo")
|
||||
.add_with(("path", "zed"))
|
||||
.add_with(("fetch-depth", "0"))
|
||||
}
|
||||
|
||||
fn checkout_extension_repo(token: &StepOutput) -> Step<Use> {
|
||||
|
|
@ -74,10 +80,74 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
.add_with(("path", "extension"))
|
||||
}
|
||||
|
||||
fn copy_workflow_files() -> Step<Run> {
|
||||
named::bash(indoc! {r#"
|
||||
fn get_previous_tag_commit() -> (Step<Run>, StepOutput) {
|
||||
let step = named::bash(formatdoc! {r#"
|
||||
PREV_COMMIT=$(git rev-parse "{ROLLOUT_TAG_NAME}^{{commit}}" 2>/dev/null || echo "")
|
||||
if [ -z "$PREV_COMMIT" ]; then
|
||||
echo "::error::No previous rollout tag '{ROLLOUT_TAG_NAME}' found. Cannot determine file changes."
|
||||
exit 1
|
||||
fi
|
||||
echo "Found previous rollout at commit: $PREV_COMMIT"
|
||||
echo "prev_commit=$PREV_COMMIT" >> "$GITHUB_OUTPUT"
|
||||
"#})
|
||||
.id("prev-tag")
|
||||
.working_directory("zed");
|
||||
|
||||
let step_output = StepOutput::new(&step, "prev_commit");
|
||||
|
||||
(step, step_output)
|
||||
}
|
||||
|
||||
fn get_removed_files(prev_commit: &StepOutput) -> (Step<Run>, StepOutput) {
|
||||
let step = named::bash(formatdoc! {r#"
|
||||
PREV_COMMIT="{prev_commit}"
|
||||
|
||||
if [ "${{{{ matrix.repo }}}}" = "workflows" ]; then
|
||||
WORKFLOW_DIR="extensions/workflows"
|
||||
else
|
||||
WORKFLOW_DIR="extensions/workflows/shared"
|
||||
fi
|
||||
|
||||
echo "Calculating changes from $PREV_COMMIT to HEAD for $WORKFLOW_DIR"
|
||||
|
||||
# Get deleted files (status D) and renamed files (status R - old name needs removal)
|
||||
# Using -M to detect renames, then extracting files that are gone from their original location
|
||||
REMOVED_FILES=$(git diff --name-status -M "$PREV_COMMIT" HEAD -- "$WORKFLOW_DIR" | \
|
||||
awk '/^D/ {{ print $2 }} /^R/ {{ print $2 }}' | \
|
||||
xargs -I{{}} basename {{}} 2>/dev/null | \
|
||||
tr '\n' ' ' || echo "")
|
||||
|
||||
REMOVED_FILES=$(echo "$REMOVED_FILES" | xargs)
|
||||
|
||||
echo "Files to remove: $REMOVED_FILES"
|
||||
echo "removed_files=$REMOVED_FILES" >> "$GITHUB_OUTPUT"
|
||||
"#})
|
||||
.id("calc-changes")
|
||||
.working_directory("zed");
|
||||
|
||||
let removed_files = StepOutput::new(&step, "removed_files");
|
||||
|
||||
(step, removed_files)
|
||||
}
|
||||
|
||||
fn sync_workflow_files(removed_files: &StepOutput) -> Step<Run> {
|
||||
named::bash(formatdoc! {r#"
|
||||
REMOVED_FILES="{removed_files}"
|
||||
|
||||
mkdir -p extension/.github/workflows
|
||||
if [ "${{ matrix.repo }}" = "workflows" ]; then
|
||||
cd extension/.github/workflows
|
||||
|
||||
if [ -n "$REMOVED_FILES" ]; then
|
||||
for file in $REMOVED_FILES; do
|
||||
if [ -f "$file" ]; then
|
||||
rm -f "$file"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
cd - > /dev/null
|
||||
|
||||
if [ "${{{{ matrix.repo }}}}" = "workflows" ]; then
|
||||
cp zed/extensions/workflows/*.yml extension/.github/workflows/
|
||||
else
|
||||
cp zed/extensions/workflows/shared/*.yml extension/.github/workflows/
|
||||
|
|
@ -86,7 +156,7 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
}
|
||||
|
||||
fn get_short_sha() -> (Step<Run>, StepOutput) {
|
||||
let step = named::bash(indoc! {r#"
|
||||
let step = named::bash(indoc::indoc! {r#"
|
||||
echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
|
||||
"#})
|
||||
.id("short-sha")
|
||||
|
|
@ -97,7 +167,7 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
(step, step_output)
|
||||
}
|
||||
|
||||
fn create_pull_request(token: &StepOutput, short_sha: StepOutput) -> Step<Use> {
|
||||
fn create_pull_request(token: &StepOutput, short_sha: &StepOutput) -> Step<Use> {
|
||||
let title = format!("Update CI workflows to `zed@{}`", short_sha);
|
||||
|
||||
named::uses("peter-evans", "create-pull-request", "v7")
|
||||
|
|
@ -105,7 +175,7 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
.add_with(("title", title.clone()))
|
||||
.add_with((
|
||||
"body",
|
||||
indoc! {r#"
|
||||
indoc::indoc! {r#"
|
||||
This PR updates the CI workflow files from the main Zed repository
|
||||
based on the commit zed-industries/zed@${{ github.sha }}
|
||||
"#},
|
||||
|
|
@ -128,7 +198,7 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
}
|
||||
|
||||
fn enable_auto_merge(token: &StepOutput) -> Step<gh_workflow::Run> {
|
||||
named::bash(indoc! {r#"
|
||||
named::bash(indoc::indoc! {r#"
|
||||
PR_NUMBER="${{ steps.create-pr.outputs.pull-request-number }}"
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
cd extension
|
||||
|
|
@ -149,6 +219,8 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
]),
|
||||
),
|
||||
);
|
||||
let (get_prev_tag, prev_commit) = get_previous_tag_commit();
|
||||
let (calc_changes, removed_files) = get_removed_files(&prev_commit);
|
||||
let (calculate_short_sha, short_sha) = get_short_sha();
|
||||
|
||||
let job = Job::default()
|
||||
|
|
@ -170,10 +242,58 @@ fn rollout_workflows_to_extension(fetch_repos_job: &NamedJob) -> NamedJob {
|
|||
.add_step(authenticate)
|
||||
.add_step(checkout_zed_repo())
|
||||
.add_step(checkout_extension_repo(&token))
|
||||
.add_step(copy_workflow_files())
|
||||
.add_step(get_prev_tag)
|
||||
.add_step(calc_changes)
|
||||
.add_step(sync_workflow_files(&removed_files))
|
||||
.add_step(calculate_short_sha)
|
||||
.add_step(create_pull_request(&token, short_sha))
|
||||
.add_step(create_pull_request(&token, &short_sha))
|
||||
.add_step(enable_auto_merge(&token));
|
||||
|
||||
named::job(job)
|
||||
}
|
||||
|
||||
fn create_rollout_tag(rollout_job: &NamedJob) -> NamedJob {
|
||||
fn checkout_zed_repo(token: &StepOutput) -> Step<Use> {
|
||||
steps::checkout_repo_with_token(token).add_with(("fetch-depth", "0"))
|
||||
}
|
||||
|
||||
fn update_rollout_tag() -> Step<Run> {
|
||||
named::bash(formatdoc! {r#"
|
||||
if git rev-parse "{ROLLOUT_TAG_NAME}" >/dev/null 2>&1; then
|
||||
git tag -d "{ROLLOUT_TAG_NAME}"
|
||||
git push origin ":refs/tags/{ROLLOUT_TAG_NAME}" || true
|
||||
fi
|
||||
|
||||
echo "Creating new tag '{ROLLOUT_TAG_NAME}' at $(git rev-parse --short HEAD)"
|
||||
git tag "{ROLLOUT_TAG_NAME}"
|
||||
git push origin "{ROLLOUT_TAG_NAME}"
|
||||
"#})
|
||||
}
|
||||
|
||||
fn configure_git() -> Step<Run> {
|
||||
named::bash(indoc! {r#"
|
||||
git config user.name "zed-zippy[bot]"
|
||||
git config user.email "234243425+zed-zippy[bot]@users.noreply.github.com"
|
||||
"#})
|
||||
}
|
||||
|
||||
let (authenticate, token) = generate_token(
|
||||
vars::ZED_ZIPPY_APP_ID,
|
||||
vars::ZED_ZIPPY_APP_PRIVATE_KEY,
|
||||
Some(
|
||||
RepositoryTarget::current()
|
||||
.permissions([("permission-contents".to_owned(), Level::Write)]),
|
||||
),
|
||||
);
|
||||
|
||||
let job = Job::default()
|
||||
.needs([rollout_job.name.clone()])
|
||||
.runs_on(runners::LINUX_SMALL)
|
||||
.timeout_minutes(1u32)
|
||||
.add_step(authenticate)
|
||||
.add_step(checkout_zed_repo(&token))
|
||||
.add_step(configure_git())
|
||||
.add_step(update_rollout_tag());
|
||||
|
||||
named::job(job)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue