History

extension_ci: Merge extension workflow files into one file (#48810)

This PR consolidates the two workflow files shipped to extensions into one, which stops us from requiring a separate runner for what can actually be done in one workflow. It also - adds a check that version bumps will now only be created by zed-zippy in separate commits. - Makes the bumping of versions faster and more reliable. - (Hopefully) fixes an issue we were seeing in some CI tests. Release Notes: - N/A

Finn Evers committed 9 months ago

Commit 82dedcb1 parent fb0af5011 files · +226 −274Browse files

Unified · Split

11 files
  1. .github/workflows/extension_bump.yml +44 −11
  2. .github/workflows/extension_release.yml +0 −45
  3. .github/workflows/extension_tests.yml +29 −1
  4. extensions/workflows/shared/release_version.yml +0 −19
  5. tooling/xtask/src/tasks/workflows.rs +0 −3
  6. tooling/xtask/src/tasks/workflows/extension_bump.rs +131 −76
  7. tooling/xtask/src/tasks/workflows/extension_release.rs +0 −75
  8. tooling/xtask/src/tasks/workflows/extension_tests.rs +19 −3
  9. tooling/xtask/src/tasks/workflows/extensions.rs +0 −1
  10. tooling/xtask/src/tasks/workflows/extensions/bump_version.rs +3 −9
  11. tooling/xtask/src/tasks/workflows/extensions/release_version.rs +0 −31
.github/workflows/extension_bump.yml+44−11
@@ -25,7 +25,7 @@ on: · 24 unmodified lines
25 description: The app secret for the corresponding app ID25 description: The app secret for the corresponding app ID
26 required: true26 required: true
27jobs:27jobs:
28 check_bump_needed:28 check_version_changed:
29 if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')29 if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
30 runs-on: namespace-profile-2x4-ubuntu-240430 runs-on: namespace-profile-2x4-ubuntu-2404
31 steps:31 steps:
@@ -51,20 +51,20 @@ jobs: · 19 unmodified lines
51 PARENT_COMMIT_VERSION="$(sed -n 's/version = \"\(.*\)\"/\1/p' < extension.toml)"51 PARENT_COMMIT_VERSION="$(sed -n 's/version = \"\(.*\)\"/\1/p' < extension.toml)"
52 52
53 [[ "$CURRENT_VERSION" == "$PARENT_COMMIT_VERSION" ]] && \53 [[ "$CURRENT_VERSION" == "$PARENT_COMMIT_VERSION" ]] && \
54 echo "needs_bump=true" >> "$GITHUB_OUTPUT" || \54 echo "version_changed=false" >> "$GITHUB_OUTPUT" || \
55 echo "needs_bump=false" >> "$GITHUB_OUTPUT"55 echo "version_changed=true" >> "$GITHUB_OUTPUT"
56 56
57 echo "current_version=${CURRENT_VERSION}" >> "$GITHUB_OUTPUT"57 echo "current_version=${CURRENT_VERSION}" >> "$GITHUB_OUTPUT"
58 outputs:58 outputs:
59 needs_bump: ${{ steps.compare-versions-check.outputs.needs_bump }}59 version_changed: ${{ steps.compare-versions-check.outputs.version_changed }}
60 current_version: ${{ steps.compare-versions-check.outputs.current_version }}60 current_version: ${{ steps.compare-versions-check.outputs.current_version }}
61 timeout-minutes: 161 timeout-minutes: 1
62 bump_extension_version:62 bump_extension_version:
63 needs:63 needs:
64 - check_bump_needed64 - check_version_changed
65 if: |-65 if: |-
66 (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') &&66 (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') &&
67 (inputs.force-bump == 'true' || needs.check_bump_needed.outputs.needs_bump == 'true')67 (inputs.force-bump == 'true' || needs.check_version_changed.outputs.version_changed == 'false')
68 runs-on: namespace-profile-2x4-ubuntu-240468 runs-on: namespace-profile-2x4-ubuntu-2404
69 steps:69 steps:
70 - id: generate-token70 - id: generate-token
@@ -82,7 +82,7 @@ jobs: · 11 unmodified lines
82 - id: bump-version82 - id: bump-version
83 name: extension_bump::bump_version83 name: extension_bump::bump_version
84 run: |84 run: |
85 OLD_VERSION="${{ needs.check_bump_needed.outputs.current_version }}"85 OLD_VERSION="${{ needs.check_version_changed.outputs.current_version }}"
86 86
87 BUMP_FILES=("extension.toml")87 BUMP_FILES=("extension.toml")
88 if [[ -f "Cargo.toml" ]]; then88 if [[ -f "Cargo.toml" ]]; then
@@ -96,7 +96,7 @@ jobs: · 7 unmodified lines
96 --no-configured-files ${{ inputs.bump-type }} "${BUMP_FILES[@]}"96 --no-configured-files ${{ inputs.bump-type }} "${BUMP_FILES[@]}"
97 97
98 if [[ -f "Cargo.toml" ]]; then98 if [[ -f "Cargo.toml" ]]; then
99 cargo update --workspace99 cargo update --workspace --offline
100 fi100 fi
101 101
102 NEW_VERSION="$(sed -n 's/version = \"\(.*\)\"/\1/p' < extension.toml)"102 NEW_VERSION="$(sed -n 's/version = \"\(.*\)\"/\1/p' < extension.toml)"
@@ -118,8 +118,8 @@ jobs: · 15 unmodified lines
118 timeout-minutes: 1118 timeout-minutes: 1
119 create_version_label:119 create_version_label:
120 needs:120 needs:
121 - check_bump_needed121 - check_version_changed
122 if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') && github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.check_bump_needed.outputs.needs_bump == 'false'122 if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') && github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.check_version_changed.outputs.version_changed == 'true'
123 runs-on: namespace-profile-2x4-ubuntu-2404123 runs-on: namespace-profile-2x4-ubuntu-2404
124 steps:124 steps:
125 - id: generate-token125 - id: generate-token
@@ -139,11 +139,44 @@ jobs: · 13 unmodified lines
139 github.rest.git.createRef({139 github.rest.git.createRef({
140 owner: context.repo.owner,140 owner: context.repo.owner,
141 repo: context.repo.repo,141 repo: context.repo.repo,
142 ref: 'refs/tags/v${{ needs.check_bump_needed.outputs.current_version }}',142 ref: 'refs/tags/v${{ needs.check_version_changed.outputs.current_version }}',
143 sha: context.sha143 sha: context.sha
144 })144 })
145 github-token: ${{ steps.generate-token.outputs.token }}145 github-token: ${{ steps.generate-token.outputs.token }}
146 timeout-minutes: 1146 timeout-minutes: 1
147 trigger_release:
148 needs:
149 - check_version_changed
150 - create_version_label
151 if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
152 runs-on: namespace-profile-2x4-ubuntu-2404
153 steps:
154 - id: generate-token
155 name: extension_bump::generate_token
156 uses: actions/create-github-app-token@v2
157 with:
158 app-id: ${{ secrets.app-id }}
159 private-key: ${{ secrets.app-secret }}
160 owner: zed-industries
161 repositories: extensions
162 - name: steps::checkout_repo
163 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
164 with:
165 clean: false
166 - id: get-extension-id
167 name: extension_bump::get_extension_id
168 run: |
169 EXTENSION_ID="$(sed -n 's/id = \"\(.*\)\"/\1/p' < extension.toml)"
170
171 echo "extension_id=${EXTENSION_ID}" >> "$GITHUB_OUTPUT"
172 - name: extension_bump::release_action
173 uses: huacnlee/zed-extension-action@v2
174 with:
175 extension-name: ${{ steps.get-extension-id.outputs.extension_id }}
176 push-to: zed-industries/extensions
177 tag: v${{ needs.check_version_changed.outputs.current_version }}
178 env:
179 COMMITTER_TOKEN: ${{ steps.generate-token.outputs.token }}
147concurrency:180concurrency:
148 group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}181 group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}
149 cancel-in-progress: true182 cancel-in-progress: true
.github/workflows/extension_release.yml+0−45
@@ -1,45 +0,0 @@
1# Generated from xtask::workflows::extension_release
2# Rebuild with `cargo xtask workflows`.
3name: extension_release
4on:
5 workflow_call:
6 secrets:
7 app-id:
8 description: The app ID used to create the PR
9 required: true
10 app-secret:
11 description: The app secret for the corresponding app ID
12 required: true
13jobs:
14 create_release:
15 if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
16 runs-on: namespace-profile-2x4-ubuntu-2404
17 steps:
18 - id: generate-token
19 name: extension_bump::generate_token
20 uses: actions/create-github-app-token@v2
21 with:
22 app-id: ${{ secrets.app-id }}
23 private-key: ${{ secrets.app-secret }}
24 owner: zed-industries
25 repositories: extensions
26 - name: steps::checkout_repo
27 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
28 with:
29 clean: false
30 - id: get-extension-id
31 name: extension_release::get_extension_id
32 run: |
33 EXTENSION_ID="$(sed -n 's/id = \"\(.*\)\"/\1/p' < extension.toml)"
34
35 echo "extension_id=${EXTENSION_ID}" >> "$GITHUB_OUTPUT"
36 - name: extension_release::release_action
37 uses: huacnlee/zed-extension-action@v2
38 with:
39 extension-name: ${{ steps.get-extension-id.outputs.extension_id }}
40 push-to: zed-industries/extensions
41 env:
42 COMMITTER_TOKEN: ${{ steps.generate-token.outputs.token }}
43defaults:
44 run:
45 shell: bash -euxo pipefail {0}
.github/workflows/extension_tests.yml+29−1
@@ -52,7 +52,7 @@ jobs: · 51 unmodified lines
52 needs:52 needs:
53 - orchestrate53 - orchestrate
54 if: needs.orchestrate.outputs.check_rust == 'true'54 if: needs.orchestrate.outputs.check_rust == 'true'
55 runs-on: namespace-profile-8x16-ubuntu-220455 runs-on: namespace-profile-8x32-ubuntu-2404
56 steps:56 steps:
57 - name: steps::checkout_repo57 - name: steps::checkout_repo
58 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af68358 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
@@ -102,6 +102,34 @@ jobs: · 43 unmodified lines
102 mkdir -p /tmp/ext-scratch102 mkdir -p /tmp/ext-scratch
103 mkdir -p /tmp/ext-output103 mkdir -p /tmp/ext-output
104 ./zed-extension --source-dir . --scratch-dir /tmp/ext-scratch --output-dir /tmp/ext-output104 ./zed-extension --source-dir . --scratch-dir /tmp/ext-scratch --output-dir /tmp/ext-output
105 - id: compare-versions-check
106 name: extension_bump::compare_versions
107 run: |
108 CURRENT_VERSION="$(sed -n 's/version = \"\(.*\)\"/\1/p' < extension.toml)"
109 PR_PARENT_SHA="${{ github.event.pull_request.head.sha }}"
110
111 if [[ -n "$PR_PARENT_SHA" ]]; then
112 git checkout "$PR_PARENT_SHA"
113 elif BRANCH_PARENT_SHA="$(git merge-base origin/main origin/zed-zippy-autobump)"; then
114 git checkout "$BRANCH_PARENT_SHA"
115 else
116 git checkout "$(git log -1 --format=%H)"~1
117 fi
118
119 PARENT_COMMIT_VERSION="$(sed -n 's/version = \"\(.*\)\"/\1/p' < extension.toml)"
120
121 [[ "$CURRENT_VERSION" == "$PARENT_COMMIT_VERSION" ]] && \
122 echo "version_changed=false" >> "$GITHUB_OUTPUT" || \
123 echo "version_changed=true" >> "$GITHUB_OUTPUT"
124
125 echo "current_version=${CURRENT_VERSION}" >> "$GITHUB_OUTPUT"
126 - name: extension_tests::verify_version_did_not_change
127 run: |
128 if [[ ${{ steps.compare-versions-check.outputs.version_changed }} == "true" && "${{ github.event_name }}" == "pull_request" && "${{ github.event.pull_request.user.login }}" != "zed-zippy[bot]" ]] ; then
129 echo "Version change detected in your change!"
130 echo "Version changes happen in separate PRs and will be performed by the zed-zippy bot"
131 exit 42
132 fi
105 timeout-minutes: 4133 timeout-minutes: 4
106 tests_pass:134 tests_pass:
107 needs:135 needs:
extensions/workflows/shared/release_version.yml+0−19
@@ -1,19 +0,0 @@
1# Generated from xtask::workflows::extensions::release_version within the Zed repository.
2# Rebuild with `cargo xtask workflows`.
3name: extensions::release_version
4on:
5 push:
6 tags:
7 - v**
8jobs:
9 call_release_version:
10 permissions:
11 contents: write
12 pull-requests: write
13 uses: zed-industries/zed/.github/workflows/extension_release.yml@main
14 secrets:
15 app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}
16 app-secret: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }}
17defaults:
18 run:
19 shell: bash -euxo pipefail {0}
tooling/xtask/src/tasks/workflows.rs+0−3
@@ -11,7 +11,6 @@ mod cherry_pick; · 10 unmodified lines
11mod compare_perf;11mod compare_perf;
12mod danger;12mod danger;
13mod extension_bump;13mod extension_bump;
14mod extension_release;
15mod extension_tests;14mod extension_tests;
16mod extension_workflow_rollout;15mod extension_workflow_rollout;
17mod extensions;16mod extensions;
@@ -135,7 +134,6 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { · 117 unmodified lines
135 WorkflowFile::zed(compare_perf::compare_perf),134 WorkflowFile::zed(compare_perf::compare_perf),
136 WorkflowFile::zed(danger::danger),135 WorkflowFile::zed(danger::danger),
137 WorkflowFile::zed(extension_bump::extension_bump),136 WorkflowFile::zed(extension_bump::extension_bump),
138 WorkflowFile::zed(extension_release::extension_release),
139 WorkflowFile::zed(extension_tests::extension_tests),137 WorkflowFile::zed(extension_tests::extension_tests),
140 WorkflowFile::zed(extension_workflow_rollout::extension_workflow_rollout),138 WorkflowFile::zed(extension_workflow_rollout::extension_workflow_rollout),
141 WorkflowFile::zed(publish_extension_cli::publish_extension_cli),139 WorkflowFile::zed(publish_extension_cli::publish_extension_cli),
@@ -149,7 +147,6 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { · 7 unmodified lines
149 /* workflows used for CI/CD in extension repositories */147 /* workflows used for CI/CD in extension repositories */
150 WorkflowFile::extension(extensions::run_tests::run_tests),148 WorkflowFile::extension(extensions::run_tests::run_tests),
151 WorkflowFile::extension_shared(extensions::bump_version::bump_version),149 WorkflowFile::extension_shared(extensions::bump_version::bump_version),
152 WorkflowFile::extension_shared(extensions::release_version::release_version),
153 ];150 ];
154 151
155 for workflow_file in workflows {152 for workflow_file in workflows {
tooling/xtask/src/tasks/workflows/extension_bump.rs+131−76
@@ -1,12 +1,12 @@
1use gh_workflow::{ctx::Context, *};1use gh_workflow::{ctx::Context, *};
2use indoc::indoc;2use indoc::{formatdoc, indoc};
3 3
4use crate::tasks::workflows::{4use crate::tasks::workflows::{
5 extension_release::extension_workflow_secrets,
6 extension_tests::{self},5 extension_tests::{self},
7 runners,6 runners,
8 steps::{7 steps::{
9 self, CommonJobConditions, DEFAULT_REPOSITORY_OWNER_GUARD, FluentBuilder, NamedJob, named,8 self, CommonJobConditions, DEFAULT_REPOSITORY_OWNER_GUARD, FluentBuilder, NamedJob,
9 checkout_repo, dependant_job, named,
10 },10 },
11 vars::{11 vars::{
12 JobOutput, StepOutput, WorkflowInput, WorkflowSecret, one_workflow_per_non_main_branch,12 JobOutput, StepOutput, WorkflowInput, WorkflowSecret, one_workflow_per_non_main_branch,
@@ -23,28 +23,34 @@ pub(crate) fn extension_bump() -> Workflow { · 10 unmodified lines
23 let force_bump = WorkflowInput::bool("force-bump", None);23 let force_bump = WorkflowInput::bool("force-bump", None);
24 24
25 let (app_id, app_secret) = extension_workflow_secrets();25 let (app_id, app_secret) = extension_workflow_secrets();
26 let (check_bump_needed, needs_bump, current_version) = check_bump_needed();26 let (check_version_changed, version_changed, current_version) = check_version_changed();
27 27
28 let needs_bump = needs_bump.as_job_output(&check_bump_needed);28 let version_changed = version_changed.as_job_output(&check_version_changed);
29 let current_version = current_version.as_job_output(&check_bump_needed);29 let current_version = current_version.as_job_output(&check_version_changed);
30 30
31 let dependencies = [&check_bump_needed];31 let dependencies = [&check_version_changed];
32 let bump_version = bump_extension_version(32 let bump_version = bump_extension_version(
33 &dependencies,33 &dependencies,
34 &current_version,34 &current_version,
35 &bump_type,35 &bump_type,
36 &needs_bump,36 &version_changed,
37 &force_bump,37 &force_bump,
38 &app_id,38 &app_id,
39 &app_secret,39 &app_secret,
40 );40 );
41 let create_label = create_version_label(41 let create_label = create_version_label(
42 &dependencies,42 &dependencies,
43 &needs_bump,43 &version_changed,
44 &current_version,44 &current_version,
45 &app_id,45 &app_id,
46 &app_secret,46 &app_secret,
47 );47 );
48 let trigger_release = trigger_release(
49 &[&check_version_changed, &create_label],
50 current_version,
51 &app_id,
52 &app_secret,
53 );
48 54
49 named::workflow()55 named::workflow()
50 .add_event(56 .add_event(
@@ -69,12 +75,13 @@ pub(crate) fn extension_bump() -> Workflow { · 18 unmodified lines
69 "ZED_EXTENSION_CLI_SHA",75 "ZED_EXTENSION_CLI_SHA",
70 extension_tests::ZED_EXTENSION_CLI_SHA,76 extension_tests::ZED_EXTENSION_CLI_SHA,
71 ))77 ))
72 .add_job(check_bump_needed.name, check_bump_needed.job)78 .add_job(check_version_changed.name, check_version_changed.job)
73 .add_job(bump_version.name, bump_version.job)79 .add_job(bump_version.name, bump_version.job)
74 .add_job(create_label.name, create_label.job)80 .add_job(create_label.name, create_label.job)
81 .add_job(trigger_release.name, trigger_release.job)
75}82}
76 83
77fn check_bump_needed() -> (NamedJob, StepOutput, StepOutput) {84fn check_version_changed() -> (NamedJob, StepOutput, StepOutput) {
78 let (compare_versions, version_changed, current_version) = compare_versions();85 let (compare_versions, version_changed, current_version) = compare_versions();
79 86
80 let job = Job::default()87 let job = Job::default()
@@ -96,7 +103,7 @@ fn check_bump_needed() -> (NamedJob, StepOutput, StepOutput) { · 15 unmodified lines
96 103
97fn create_version_label(104fn create_version_label(
98 dependencies: &[&NamedJob],105 dependencies: &[&NamedJob],
99 needs_bump: &JobOutput,106 version_changed_output: &JobOutput,
100 current_version: &JobOutput,107 current_version: &JobOutput,
101 app_id: &WorkflowSecret,108 app_id: &WorkflowSecret,
102 app_secret: &WorkflowSecret,109 app_secret: &WorkflowSecret,
@@ -105,8 +112,9 @@ fn create_version_label( · 2 unmodified lines
105 generate_token(&app_id.to_string(), &app_secret.to_string(), None);112 generate_token(&app_id.to_string(), &app_secret.to_string(), None);
106 let job = steps::dependant_job(dependencies)113 let job = steps::dependant_job(dependencies)
107 .cond(Expression::new(format!(114 .cond(Expression::new(format!(
108 "{DEFAULT_REPOSITORY_OWNER_GUARD} && github.event_name == 'push' && github.ref == 'refs/heads/main' && {} == 'false'",115 "{DEFAULT_REPOSITORY_OWNER_GUARD} && github.event_name == 'push' && \
109 needs_bump.expr(),116 github.ref == 'refs/heads/main' && {version_changed} == 'true'",
117 version_changed = version_changed_output.expr(),
110 )))118 )))
111 .runs_on(runners::LINUX_SMALL)119 .runs_on(runners::LINUX_SMALL)
112 .timeout_minutes(1u32)120 .timeout_minutes(1u32)
@@ -122,28 +130,24 @@ fn create_version_tag(current_version: &JobOutput, generated_token: StepOutput) · 9 unmodified lines
122 Input::default()130 Input::default()
123 .add(131 .add(
124 "script",132 "script",
125 format!(133 formatdoc! {r#"
126 indoc! {r#"134 github.rest.git.createRef({{
127 github.rest.git.createRef({{135 owner: context.repo.owner,
128 owner: context.repo.owner,136 repo: context.repo.repo,
129 repo: context.repo.repo,137 ref: 'refs/tags/v{current_version}',
130 ref: 'refs/tags/v{}',138 sha: context.sha
131 sha: context.sha139 }})"#
132 }})"#140 },
133 },
134 current_version
135 ),
136 )141 )
137 .add("github-token", generated_token.to_string()),142 .add("github-token", generated_token.to_string()),
138 )143 )
139}144}
140 145
141/// Compares the current and previous commit and checks whether versions changed inbetween.146/// Compares the current and previous commit and checks whether versions changed inbetween.
142fn compare_versions() -> (Step<Run>, StepOutput, StepOutput) {147pub(crate) fn compare_versions() -> (Step<Run>, StepOutput, StepOutput) {
143 let check_needs_bump = named::bash(format!(148 let check_needs_bump = named::bash(formatdoc! {
144 indoc! {149 r#"
145 r#"150 CURRENT_VERSION="$({VERSION_CHECK})"
146 CURRENT_VERSION="$({})"
147 PR_PARENT_SHA="${{{{ github.event.pull_request.head.sha }}}}"151 PR_PARENT_SHA="${{{{ github.event.pull_request.head.sha }}}}"
148 152
149 if [[ -n "$PR_PARENT_SHA" ]]; then153 if [[ -n "$PR_PARENT_SHA" ]]; then
@@ -154,31 +158,29 @@ fn compare_versions() -> (Step<Run>, StepOutput, StepOutput) { · 4 unmodified lines
154 git checkout "$(git log -1 --format=%H)"~1158 git checkout "$(git log -1 --format=%H)"~1
155 fi159 fi
156 160
157 PARENT_COMMIT_VERSION="$({})"161 PARENT_COMMIT_VERSION="$({VERSION_CHECK})"
158 162
159 [[ "$CURRENT_VERSION" == "$PARENT_COMMIT_VERSION" ]] && \163 [[ "$CURRENT_VERSION" == "$PARENT_COMMIT_VERSION" ]] && \
160 echo "needs_bump=true" >> "$GITHUB_OUTPUT" || \164 echo "version_changed=false" >> "$GITHUB_OUTPUT" || \
161 echo "needs_bump=false" >> "$GITHUB_OUTPUT"165 echo "version_changed=true" >> "$GITHUB_OUTPUT"
162 166
163 echo "current_version=${{CURRENT_VERSION}}" >> "$GITHUB_OUTPUT"167 echo "current_version=${{CURRENT_VERSION}}" >> "$GITHUB_OUTPUT"
164 "#168 "#
165 },169 })
166 VERSION_CHECK, VERSION_CHECK
167 ))
168 .id("compare-versions-check");170 .id("compare-versions-check");
169 171
170 let needs_bump = StepOutput::new(&check_needs_bump, "needs_bump");172 let version_changed = StepOutput::new(&check_needs_bump, "version_changed");
171 let current_version = StepOutput::new(&check_needs_bump, "current_version");173 let current_version = StepOutput::new(&check_needs_bump, "current_version");
172 174
173 (check_needs_bump, needs_bump, current_version)175 (check_needs_bump, version_changed, current_version)
174}176}
175 177
176fn bump_extension_version(178fn bump_extension_version(
177 dependencies: &[&NamedJob],179 dependencies: &[&NamedJob],
178 current_version: &JobOutput,180 current_version: &JobOutput,
179 bump_type: &WorkflowInput,181 bump_type: &WorkflowInput,
180 needs_bump: &JobOutput,182 version_changed_output: &JobOutput,
181 force_bump: &WorkflowInput,183 force_bump_output: &WorkflowInput,
182 app_id: &WorkflowSecret,184 app_id: &WorkflowSecret,
183 app_secret: &WorkflowSecret,185 app_secret: &WorkflowSecret,
184) -> NamedJob {186) -> NamedJob {
@@ -188,9 +190,9 @@ fn bump_extension_version( · 3 unmodified lines
188 190
189 let job = steps::dependant_job(dependencies)191 let job = steps::dependant_job(dependencies)
190 .cond(Expression::new(format!(192 .cond(Expression::new(format!(
191 "{DEFAULT_REPOSITORY_OWNER_GUARD} &&\n({} == 'true' || {} == 'true')",193 "{DEFAULT_REPOSITORY_OWNER_GUARD} &&\n({force_bump} == 'true' || {version_changed} == 'false')",
192 force_bump.expr(),194 force_bump = force_bump_output.expr(),
193 needs_bump.expr(),195 version_changed = version_changed_output.expr(),
194 )))196 )))
195 .runs_on(runners::LINUX_SMALL)197 .runs_on(runners::LINUX_SMALL)
196 .timeout_minutes(1u32)198 .timeout_minutes(1u32)
@@ -254,32 +256,29 @@ fn install_bump_2_version() -> Step<Run> { · 57 unmodified lines
254}256}
255 257
256fn bump_version(current_version: &JobOutput, bump_type: &WorkflowInput) -> (Step<Run>, StepOutput) {258fn bump_version(current_version: &JobOutput, bump_type: &WorkflowInput) -> (Step<Run>, StepOutput) {
257 let step = named::bash(format!(259 let step = named::bash(formatdoc! {r#"
258 indoc! {r#"260 OLD_VERSION="{current_version}"
259 OLD_VERSION="{}"261
260 262 BUMP_FILES=("extension.toml")
261 BUMP_FILES=("extension.toml")263 if [[ -f "Cargo.toml" ]]; then
262 if [[ -f "Cargo.toml" ]]; then264 BUMP_FILES+=("Cargo.toml")
263 BUMP_FILES+=("Cargo.toml")265 fi
264 fi266
265 267 bump2version \
266 bump2version \268 --search "version = \"{{current_version}}"\" \
267 --search "version = \"{{current_version}}"\" \269 --replace "version = \"{{new_version}}"\" \
268 --replace "version = \"{{new_version}}"\" \270 --current-version "$OLD_VERSION" \
269 --current-version "$OLD_VERSION" \271 --no-configured-files {bump_type} "${{BUMP_FILES[@]}}"
270 --no-configured-files {} "${{BUMP_FILES[@]}}"272
271 273 if [[ -f "Cargo.toml" ]]; then
272 if [[ -f "Cargo.toml" ]]; then274 cargo update --workspace --offline
273 cargo update --workspace275 fi
274 fi276
275 277 NEW_VERSION="$({VERSION_CHECK})"
276 NEW_VERSION="$({})"278
277 279 echo "new_version=${{NEW_VERSION}}" >> "$GITHUB_OUTPUT"
278 echo "new_version=${{NEW_VERSION}}" >> "$GITHUB_OUTPUT"280 "#
279 "#281 })
280 },
281 current_version, bump_type, VERSION_CHECK
282 ))
283 .id("bump-version");282 .id("bump-version");
284 283
285 let new_version = StepOutput::new(&step, "new_version");284 let new_version = StepOutput::new(&step, "new_version");
@@ -287,21 +286,18 @@ fn bump_version(current_version: &JobOutput, bump_type: &WorkflowInput) -> (Step · 1 unmodified line
287}286}
288 287
289fn create_pull_request(new_version: StepOutput, generated_token: StepOutput) -> Step<Use> {288fn create_pull_request(new_version: StepOutput, generated_token: StepOutput) -> Step<Use> {
290 let formatted_version = format!("v{}", new_version);289 let formatted_version = format!("v{new_version}");
291 290
292 named::uses("peter-evans", "create-pull-request", "v7").with(291 named::uses("peter-evans", "create-pull-request", "v7").with(
293 Input::default()292 Input::default()
294 .add("title", format!("Bump version to {}", new_version))293 .add("title", format!("Bump version to {new_version}"))
295 .add(294 .add(
296 "body",295 "body",
297 format!(296 format!("This PR bumps the version of this extension to {formatted_version}",),
298 "This PR bumps the version of this extension to {}",
299 formatted_version
300 ),
301 )297 )
302 .add(298 .add(
303 "commit-message",299 "commit-message",
304 format!("Bump version to {}", formatted_version),300 format!("Bump version to {formatted_version}"),
305 )301 )
306 .add("branch", "zed-zippy-autobump")302 .add("branch", "zed-zippy-autobump")
307 .add(303 .add(
@@ -316,6 +312,65 @@ fn create_pull_request(new_version: StepOutput, generated_token: StepOutput) -> · 8 unmodified lines
316 )312 )
317}313}
318 314
315fn trigger_release(
316 dependencies: &[&NamedJob],
317 version: JobOutput,
318 app_id: &WorkflowSecret,
319 app_secret: &WorkflowSecret,
320) -> NamedJob {
321 let extension_registry = RepositoryTarget::new("zed-industries", &["extensions"]);
322 let (generate_token, generated_token) = generate_token(
323 &app_id.to_string(),
324 &app_secret.to_string(),
325 Some(extension_registry),
326 );
327 let (get_extension_id, extension_id) = get_extension_id();
328
329 let job = dependant_job(dependencies)
330 .with_repository_owner_guard()
331 .runs_on(runners::LINUX_SMALL)
332 .add_step(generate_token)
333 .add_step(checkout_repo())
334 .add_step(get_extension_id)
335 .add_step(release_action(extension_id, version, generated_token));
336
337 named::job(job)
338}
339
340fn get_extension_id() -> (Step<Run>, StepOutput) {
341 let step = named::bash(indoc! {
342 r#"
343 EXTENSION_ID="$(sed -n 's/id = \"\(.*\)\"/\1/p' < extension.toml)"
344
345 echo "extension_id=${EXTENSION_ID}" >> "$GITHUB_OUTPUT"
346 "#})
347 .id("get-extension-id");
348
349 let extension_id = StepOutput::new(&step, "extension_id");
350
351 (step, extension_id)
352}
353
354fn release_action(
355 extension_id: StepOutput,
356 version: JobOutput,
357 generated_token: StepOutput,
358) -> Step<Use> {
359 named::uses("huacnlee", "zed-extension-action", "v2")
360 .add_with(("extension-name", extension_id.to_string()))
361 .add_with(("push-to", "zed-industries/extensions"))
362 .add_with(("tag", format!("v{version}")))
363 .add_env(("COMMITTER_TOKEN", generated_token.to_string()))
364}
365
366fn extension_workflow_secrets() -> (WorkflowSecret, WorkflowSecret) {
367 let app_id = WorkflowSecret::new("app-id", "The app ID used to create the PR");
368 let app_secret =
369 WorkflowSecret::new("app-secret", "The app secret for the corresponding app ID");
370
371 (app_id, app_secret)
372}
373
319pub(crate) struct RepositoryTarget {374pub(crate) struct RepositoryTarget {
320 owner: Option<String>,375 owner: Option<String>,
321 repositories: Option<String>,376 repositories: Option<String>,
tooling/xtask/src/tasks/workflows/extension_release.rs+0−75
@@ -1,75 +0,0 @@
1use gh_workflow::{Event, Job, Run, Step, Use, Workflow, WorkflowCall};
2use indoc::indoc;
3
4use crate::tasks::workflows::{
5 extension_bump::{RepositoryTarget, generate_token},
6 runners,
7 steps::{CommonJobConditions, NamedJob, checkout_repo, named},
8 vars::{StepOutput, WorkflowSecret},
9};
10
11pub(crate) fn extension_release() -> Workflow {
12 let (app_id, app_secret) = extension_workflow_secrets();
13
14 let create_release = create_release(&app_id, &app_secret);
15 named::workflow()
16 .on(
17 Event::default().workflow_call(WorkflowCall::default().secrets([
18 (app_id.name.to_owned(), app_id.secret_configuration()),
19 (
20 app_secret.name.to_owned(),
21 app_secret.secret_configuration(),
22 ),
23 ])),
24 )
25 .add_job(create_release.name, create_release.job)
26}
27
28fn create_release(app_id: &WorkflowSecret, app_secret: &WorkflowSecret) -> NamedJob {
29 let extension_registry = RepositoryTarget::new("zed-industries", &["extensions"]);
30 let (generate_token, generated_token) = generate_token(
31 &app_id.to_string(),
32 &app_secret.to_string(),
33 Some(extension_registry),
34 );
35 let (get_extension_id, extension_id) = get_extension_id();
36
37 let job = Job::default()
38 .with_repository_owner_guard()
39 .runs_on(runners::LINUX_SMALL)
40 .add_step(generate_token)
41 .add_step(checkout_repo())
42 .add_step(get_extension_id)
43 .add_step(release_action(extension_id, generated_token));
44
45 named::job(job)
46}
47
48fn get_extension_id() -> (Step<Run>, StepOutput) {
49 let step = named::bash(indoc! {
50 r#"
51 EXTENSION_ID="$(sed -n 's/id = \"\(.*\)\"/\1/p' < extension.toml)"
52
53 echo "extension_id=${EXTENSION_ID}" >> "$GITHUB_OUTPUT"
54 "#})
55 .id("get-extension-id");
56
57 let extension_id = StepOutput::new(&step, "extension_id");
58
59 (step, extension_id)
60}
61
62fn release_action(extension_id: StepOutput, generated_token: StepOutput) -> Step<Use> {
63 named::uses("huacnlee", "zed-extension-action", "v2")
64 .add_with(("extension-name", extension_id.to_string()))
65 .add_with(("push-to", "zed-industries/extensions"))
66 .add_env(("COMMITTER_TOKEN", generated_token.to_string()))
67}
68
69pub(crate) fn extension_workflow_secrets() -> (WorkflowSecret, WorkflowSecret) {
70 let app_id = WorkflowSecret::new("app-id", "The app ID used to create the PR");
71 let app_secret =
72 WorkflowSecret::new("app-secret", "The app secret for the corresponding app ID");
73
74 (app_id, app_secret)
75}
tooling/xtask/src/tasks/workflows/extension_tests.rs+19−3
@@ -1,7 +1,8 @@
1use gh_workflow::*;1use gh_workflow::*;
2use indoc::indoc;2use indoc::{formatdoc, indoc};
3 3
4use crate::tasks::workflows::{4use crate::tasks::workflows::{
5 extension_bump::compare_versions,
5 run_tests::{orchestrate_without_package_filter, tests_pass},6 run_tests::{orchestrate_without_package_filter, tests_pass},
6 runners,7 runners,
7 steps::{self, CommonJobConditions, FluentBuilder, NamedJob, named},8 steps::{self, CommonJobConditions, FluentBuilder, NamedJob, named},
@@ -58,7 +59,7 @@ fn run_clippy() -> Step<Run> { · 50 unmodified lines
58fn check_rust() -> NamedJob {59fn check_rust() -> NamedJob {
59 let job = Job::default()60 let job = Job::default()
60 .with_repository_owner_guard()61 .with_repository_owner_guard()
61 .runs_on(runners::LINUX_LARGE)62 .runs_on(runners::LINUX_LARGE_RAM)
62 .timeout_minutes(6u32)63 .timeout_minutes(6u32)
63 .add_step(steps::checkout_repo())64 .add_step(steps::checkout_repo())
64 .add_step(steps::cache_rust_dependencies_namespace())65 .add_step(steps::cache_rust_dependencies_namespace())
@@ -78,6 +79,8 @@ fn check_rust() -> NamedJob { · 13 unmodified lines
78 79
79pub(crate) fn check_extension() -> NamedJob {80pub(crate) fn check_extension() -> NamedJob {
80 let (cache_download, cache_hit) = cache_zed_extension_cli();81 let (cache_download, cache_hit) = cache_zed_extension_cli();
82 let (check_version_job, version_changed, _) = compare_versions();
83
81 let job = Job::default()84 let job = Job::default()
82 .with_repository_owner_guard()85 .with_repository_owner_guard()
83 .runs_on(runners::LINUX_LARGE_RAM)86 .runs_on(runners::LINUX_LARGE_RAM)
@@ -85,7 +88,9 @@ pub(crate) fn check_extension() -> NamedJob { · 1 unmodified line
85 .add_step(steps::checkout_repo())88 .add_step(steps::checkout_repo())
86 .add_step(cache_download)89 .add_step(cache_download)
87 .add_step(download_zed_extension_cli(cache_hit))90 .add_step(download_zed_extension_cli(cache_hit))
88 .add_step(check());91 .add_step(check())
92 .add_step(check_version_job)
93 .add_step(verify_version_did_not_change(version_changed));
89 94
90 named::job(job)95 named::job(job)
91}96}
@@ -126,3 +131,14 @@ pub fn check() -> Step<Run> { · 34 unmodified lines
126 "#131 "#
127 })132 })
128}133}
134
135fn verify_version_did_not_change(version_changed: StepOutput) -> Step<Run> {
136 named::bash(formatdoc! {r#"
137 if [[ {version_changed} == "true" && "${{{{ github.event_name }}}}" == "pull_request" && "${{{{ github.event.pull_request.user.login }}}}" != "zed-zippy[bot]" ]] ; then
138 echo "Version change detected in your change!"
139 echo "Version changes happen in separate PRs and will be performed by the zed-zippy bot"
140 exit 42
141 fi
142 "#
143 })
144}
tooling/xtask/src/tasks/workflows/extensions.rs+0−1
@@ -4,7 +4,6 @@ use indexmap::IndexMap; · 3 unmodified lines
4use crate::tasks::workflows::vars;4use crate::tasks::workflows::vars;
5 5
6pub(crate) mod bump_version;6pub(crate) mod bump_version;
7pub(crate) mod release_version;
8pub(crate) mod run_tests;7pub(crate) mod run_tests;
9 8
10pub(crate) trait WithAppSecrets: Sized {9pub(crate) trait WithAppSecrets: Sized {
tooling/xtask/src/tasks/workflows/extensions/bump_version.rs+3−9
@@ -2,13 +2,13 @@ use gh_workflow::{ · 1 unmodified line
2 Event, Expression, Input, Job, Level, Permissions, PullRequest, PullRequestType, Push, Run,2 Event, Expression, Input, Job, Level, Permissions, PullRequest, PullRequestType, Push, Run,
3 Step, UsesJob, Workflow, WorkflowDispatch,3 Step, UsesJob, Workflow, WorkflowDispatch,
4};4};
5use indexmap::IndexMap;
6use indoc::indoc;5use indoc::indoc;
7 6
8use crate::tasks::workflows::{7use crate::tasks::workflows::{
8 extensions::WithAppSecrets,
9 runners,9 runners,
10 steps::{CommonJobConditions, NamedJob, named},10 steps::{CommonJobConditions, NamedJob, named},
11 vars::{self, JobOutput, StepOutput, one_workflow_per_non_main_branch_and_token},11 vars::{JobOutput, StepOutput, one_workflow_per_non_main_branch_and_token},
12};12};
13 13
14pub(crate) fn bump_version() -> Workflow {14pub(crate) fn bump_version() -> Workflow {
@@ -59,13 +59,7 @@ pub(crate) fn call_bump_version( · 44 unmodified lines
59 .add("bump-type", bump_type.to_string())59 .add("bump-type", bump_type.to_string())
60 .add("force-bump", true),60 .add("force-bump", true),
61 )61 )
62 .secrets(IndexMap::from([62 .with_app_secrets();
63 ("app-id".to_owned(), vars::ZED_ZIPPY_APP_ID.to_owned()),
64 (
65 "app-secret".to_owned(),
66 vars::ZED_ZIPPY_APP_PRIVATE_KEY.to_owned(),
67 ),
68 ]));
69 63
70 named::job(job)64 named::job(job)
71}65}
tooling/xtask/src/tasks/workflows/extensions/release_version.rs+0−31
@@ -1,31 +0,0 @@
1use gh_workflow::{Event, Job, Level, Permissions, Push, UsesJob, Workflow};
2
3use crate::tasks::workflows::{
4 extensions::WithAppSecrets,
5 steps::{NamedJob, named},
6};
7
8pub(crate) fn release_version() -> Workflow {
9 let create_release = call_release_version();
10 named::workflow()
11 .on(Event::default().push(Push::default().add_tag("v**")))
12 .add_job(create_release.name, create_release.job)
13}
14
15pub(crate) fn call_release_version() -> NamedJob<UsesJob> {
16 let job = Job::default()
17 .permissions(
18 Permissions::default()
19 .contents(Level::Write)
20 .pull_requests(Level::Write),
21 )
22 .uses(
23 "zed-industries",
24 "zed",
25 ".github/workflows/extension_release.yml",
26 "main",
27 )
28 .with_app_secrets();
29
30 named::job(job)
31}