extension_ci: Specify needed permissions for jobs (#45542)

Finn Evers created

GitHub flags these as security vulnerabilities. Hence, this PR specifies
the needed permissions for the workflows used in the `zed-extensions`
organization.

Release Notes:

- N/A

Change summary

.github/workflows/extension_bump.yml                            |  4 
.github/workflows/extension_release.yml                         |  2 
extensions/workflows/bump_version.yml                           |  9 +
extensions/workflows/release_version.yml                        |  3 
extensions/workflows/run_tests.yml                              |  2 
tooling/xtask/src/tasks/workflows/extension_bump.rs             |  4 
tooling/xtask/src/tasks/workflows/extension_release.rs          |  2 
tooling/xtask/src/tasks/workflows/extensions/bump_version.rs    | 17 ++
tooling/xtask/src/tasks/workflows/extensions/release_version.rs |  7 +
tooling/xtask/src/tasks/workflows/extensions/run_tests.rs       | 16 +-
10 files changed, 47 insertions(+), 19 deletions(-)

Detailed changes

.github/workflows/extension_bump.yml 🔗

@@ -66,7 +66,7 @@ jobs:
     if: |-
       (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions') &&
       (inputs.force-bump == 'true' || needs.check_bump_needed.outputs.needs_bump == 'true')
-    runs-on: namespace-profile-8x16-ubuntu-2204
+    runs-on: namespace-profile-2x4-ubuntu-2404
     steps:
     - id: generate-token
       name: extension_bump::generate_token
@@ -119,7 +119,7 @@ jobs:
     needs:
     - check_bump_needed
     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'
-    runs-on: namespace-profile-8x16-ubuntu-2204
+    runs-on: namespace-profile-2x4-ubuntu-2404
     steps:
     - id: generate-token
       name: extension_bump::generate_token

.github/workflows/extension_release.yml 🔗

@@ -13,7 +13,7 @@ on:
 jobs:
   create_release:
     if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
-    runs-on: namespace-profile-8x16-ubuntu-2204
+    runs-on: namespace-profile-2x4-ubuntu-2404
     steps:
     - id: generate-token
       name: extension_bump::generate_token

extensions/workflows/bump_version.yml 🔗

@@ -13,7 +13,9 @@ on:
   workflow_dispatch: {}
 jobs:
   determine_bump_type:
-    runs-on: namespace-profile-16x32-ubuntu-2204
+    if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
+    runs-on: namespace-profile-2x4-ubuntu-2404
+    permissions: {}
     steps:
     - id: get-bump-type
       name: extensions::bump_version::get_bump_type
@@ -40,6 +42,11 @@ jobs:
     needs:
     - determine_bump_type
     if: github.event.action != 'labeled' || needs.determine_bump_type.outputs.bump_type != 'patch'
+    permissions:
+      actions: write
+      contents: write
+      issues: write
+      pull-requests: write
     uses: zed-industries/zed/.github/workflows/extension_bump.yml@main
     secrets:
       app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}

extensions/workflows/release_version.yml 🔗

@@ -7,6 +7,9 @@ on:
     - v**
 jobs:
   call_release_version:
+    permissions:
+      contents: write
+      pull-requests: write
     uses: zed-industries/zed/.github/workflows/extension_release.yml@main
     secrets:
       app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}

extensions/workflows/run_tests.yml 🔗

@@ -10,6 +10,8 @@ on:
     - main
 jobs:
   call_extension_tests:
+    permissions:
+      contents: read
     uses: zed-industries/zed/.github/workflows/extension_tests.yml@main
 concurrency:
   group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.ref_name == 'main' && github.sha || 'anysha' }}pr

tooling/xtask/src/tasks/workflows/extension_bump.rs 🔗

@@ -107,7 +107,7 @@ fn create_version_label(
             "{DEFAULT_REPOSITORY_OWNER_GUARD} && github.event_name == 'push' && github.ref == 'refs/heads/main' && {} == 'false'",
             needs_bump.expr(),
         )))
-        .runs_on(runners::LINUX_LARGE)
+        .runs_on(runners::LINUX_SMALL)
         .timeout_minutes(1u32)
         .add_step(generate_token)
         .add_step(steps::checkout_repo())
@@ -190,7 +190,7 @@ fn bump_extension_version(
             force_bump.expr(),
             needs_bump.expr(),
         )))
-        .runs_on(runners::LINUX_LARGE)
+        .runs_on(runners::LINUX_SMALL)
         .timeout_minutes(1u32)
         .add_step(generate_token)
         .add_step(steps::checkout_repo())

tooling/xtask/src/tasks/workflows/extension_release.rs 🔗

@@ -33,7 +33,7 @@ fn create_release(app_id: &WorkflowSecret, app_secret: &WorkflowSecret) -> Named
 
     let job = Job::default()
         .with_repository_owner_guard()
-        .runs_on(runners::LINUX_LARGE)
+        .runs_on(runners::LINUX_SMALL)
         .add_step(generate_token)
         .add_step(checkout_repo())
         .add_step(get_extension_id)

tooling/xtask/src/tasks/workflows/extensions/bump_version.rs 🔗

@@ -1,13 +1,13 @@
 use gh_workflow::{
-    Event, Expression, Input, Job, PullRequest, PullRequestType, Push, Run, Step, UsesJob,
-    Workflow, WorkflowDispatch,
+    Event, Expression, Input, Job, Level, Permissions, PullRequest, PullRequestType, Push, Run,
+    Step, UsesJob, Workflow, WorkflowDispatch,
 };
 use indexmap::IndexMap;
 use indoc::indoc;
 
 use crate::tasks::workflows::{
     runners,
-    steps::{NamedJob, named},
+    steps::{CommonJobConditions, NamedJob, named},
     vars::{self, JobOutput, StepOutput, one_workflow_per_non_main_branch_and_token},
 };
 
@@ -40,6 +40,13 @@ pub(crate) fn call_bump_version(
             "github.event.action != 'labeled' || {} != 'patch'",
             bump_type.expr()
         )))
+        .permissions(
+            Permissions::default()
+                .contents(Level::Write)
+                .issues(Level::Write)
+                .pull_requests(Level::Write)
+                .actions(Level::Write),
+        )
         .uses(
             "zed-industries",
             "zed",
@@ -66,7 +73,9 @@ pub(crate) fn call_bump_version(
 fn determine_bump_type() -> (NamedJob, StepOutput) {
     let (get_bump_type, output) = get_bump_type();
     let job = Job::default()
-        .runs_on(runners::LINUX_DEFAULT)
+        .with_repository_owner_guard()
+        .permissions(Permissions::default())
+        .runs_on(runners::LINUX_SMALL)
         .add_step(get_bump_type)
         .outputs([(output.name.to_owned(), output.to_string())]);
     (named::job(job), output)

tooling/xtask/src/tasks/workflows/extensions/release_version.rs 🔗

@@ -1,4 +1,4 @@
-use gh_workflow::{Event, Job, Push, UsesJob, Workflow};
+use gh_workflow::{Event, Job, Level, Permissions, Push, UsesJob, Workflow};
 
 use crate::tasks::workflows::{
     extensions::WithAppSecrets,
@@ -14,6 +14,11 @@ pub(crate) fn release_version() -> Workflow {
 
 pub(crate) fn call_release_version() -> NamedJob<UsesJob> {
     let job = Job::default()
+        .permissions(
+            Permissions::default()
+                .contents(Level::Write)
+                .pull_requests(Level::Write),
+        )
         .uses(
             "zed-industries",
             "zed",

tooling/xtask/src/tasks/workflows/extensions/run_tests.rs 🔗

@@ -1,4 +1,4 @@
-use gh_workflow::{Event, Job, PullRequest, Push, UsesJob, Workflow};
+use gh_workflow::{Event, Job, Level, Permissions, PullRequest, Push, UsesJob, Workflow};
 
 use crate::tasks::workflows::{
     steps::{NamedJob, named},
@@ -16,12 +16,14 @@ pub(crate) fn run_tests() -> Workflow {
 }
 
 pub(crate) fn call_extension_tests() -> NamedJob<UsesJob> {
-    let job = Job::default().uses(
-        "zed-industries",
-        "zed",
-        ".github/workflows/extension_tests.yml",
-        "main",
-    );
+    let job = Job::default()
+        .permissions(Permissions::default().contents(Level::Read))
+        .uses(
+            "zed-industries",
+            "zed",
+            ".github/workflows/extension_tests.yml",
+            "main",
+        );
 
     named::job(job)
 }