mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
ci: Set explicit permissions for Zed Zippy (#52895)
This hopefully fixes the permission issues we are seeing with the Zed Zippy cherry picks Release Notes: - N/A
This commit is contained in:
parent
5a9c763d9a
commit
a212304ed2
10 changed files with 88 additions and 46 deletions
2
.github/workflows/autofix_pr.yml
vendored
2
.github/workflows/autofix_pr.yml
vendored
|
|
@ -97,6 +97,8 @@ jobs:
|
|||
with:
|
||||
app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}
|
||||
private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }}
|
||||
permission-contents: write
|
||||
permission-workflows: write
|
||||
- name: steps::checkout_repo
|
||||
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
|
||||
with:
|
||||
|
|
|
|||
2
.github/workflows/cherry_pick.yml
vendored
2
.github/workflows/cherry_pick.yml
vendored
|
|
@ -35,6 +35,8 @@ jobs:
|
|||
with:
|
||||
app-id: ${{ secrets.ZED_ZIPPY_APP_ID }}
|
||||
private-key: ${{ secrets.ZED_ZIPPY_APP_PRIVATE_KEY }}
|
||||
permission-contents: write
|
||||
permission-workflows: write
|
||||
- name: cherry_pick::run_cherry_pick::cherry_pick
|
||||
run: ./script/cherry-pick "$BRANCH" "$COMMIT" "$CHANNEL"
|
||||
env:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use gh_workflow::*;
|
|||
|
||||
use crate::tasks::workflows::{
|
||||
runners,
|
||||
steps::{self, FluentBuilder, NamedJob, named},
|
||||
steps::{self, FluentBuilder, NamedJob, RepositoryTarget, TokenPermissions, named},
|
||||
vars::{self, StepOutput, WorkflowInput},
|
||||
};
|
||||
|
||||
|
|
@ -161,7 +161,13 @@ fn commit_changes(pr_number: &WorkflowInput, autofix_job: &NamedJob) -> NamedJob
|
|||
.add_env(("GITHUB_TOKEN", token))
|
||||
}
|
||||
|
||||
let (authenticate, token) = steps::authenticate_as_zippy();
|
||||
let (authenticate, token) = steps::authenticate_as_zippy()
|
||||
.for_repository(RepositoryTarget::current())
|
||||
.with_permissions([
|
||||
(TokenPermissions::Contents, Level::Write),
|
||||
(TokenPermissions::Workflows, Level::Write),
|
||||
])
|
||||
.into();
|
||||
|
||||
named::job(
|
||||
Job::default()
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ fn run_bump_patch_version(branch: &WorkflowInput) -> steps::NamedJob {
|
|||
.add_env(("GITHUB_TOKEN", token))
|
||||
}
|
||||
|
||||
let (authenticate, token) = steps::authenticate_as_zippy();
|
||||
let (authenticate, token) = steps::authenticate_as_zippy().into();
|
||||
|
||||
named::job(
|
||||
Job::default()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use gh_workflow::*;
|
|||
|
||||
use crate::tasks::workflows::{
|
||||
runners,
|
||||
steps::{self, NamedJob, named},
|
||||
steps::{self, NamedJob, RepositoryTarget, TokenPermissions, named},
|
||||
vars::{StepOutput, WorkflowInput},
|
||||
};
|
||||
|
||||
|
|
@ -44,7 +44,13 @@ fn run_cherry_pick(
|
|||
.add_env(("GITHUB_TOKEN", token))
|
||||
}
|
||||
|
||||
let (authenticate, token) = steps::authenticate_as_zippy();
|
||||
let (authenticate, token) = steps::authenticate_as_zippy()
|
||||
.for_repository(RepositoryTarget::current())
|
||||
.with_permissions([
|
||||
(TokenPermissions::Contents, Level::Write),
|
||||
(TokenPermissions::Workflows, Level::Write),
|
||||
])
|
||||
.into();
|
||||
|
||||
named::job(
|
||||
Job::default()
|
||||
|
|
|
|||
|
|
@ -359,7 +359,8 @@ fn trigger_release(
|
|||
let extension_registry = RepositoryTarget::new("zed-industries", &["extensions"]);
|
||||
let (generate_token, generated_token) =
|
||||
generate_token(&app_id.to_string(), &app_secret.to_string())
|
||||
.for_repository(extension_registry);
|
||||
.for_repository(extension_registry)
|
||||
.into();
|
||||
let (get_extension_id, extension_id) = get_extension_id();
|
||||
let (release_action, pull_request_number) = release_action(extension_id, tag, &generated_token);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use indoc::indoc;
|
|||
use serde_json::json;
|
||||
|
||||
use crate::tasks::workflows::steps::CheckoutStep;
|
||||
use crate::tasks::workflows::steps::TokenPermissions;
|
||||
use crate::tasks::workflows::steps::cache_rust_dependencies_namespace;
|
||||
use crate::tasks::workflows::vars::JobOutput;
|
||||
use crate::tasks::workflows::{
|
||||
|
|
@ -309,13 +310,17 @@ fn rollout_workflows_to_extension(
|
|||
}
|
||||
|
||||
let (authenticate, token) =
|
||||
generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY).for_repository(
|
||||
RepositoryTarget::new("zed-extensions", &["${{ matrix.repo }}"]).permissions([
|
||||
("permission-pull-requests".to_owned(), Level::Write),
|
||||
("permission-contents".to_owned(), Level::Write),
|
||||
("permission-workflows".to_owned(), Level::Write),
|
||||
]),
|
||||
);
|
||||
generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY)
|
||||
.for_repository(RepositoryTarget::new(
|
||||
"zed-extensions",
|
||||
&["${{ matrix.repo }}"],
|
||||
))
|
||||
.with_permissions([
|
||||
(TokenPermissions::PullRequests, Level::Write),
|
||||
(TokenPermissions::Contents, Level::Write),
|
||||
(TokenPermissions::Workflows, Level::Write),
|
||||
])
|
||||
.into();
|
||||
|
||||
let (calculate_short_sha, short_sha) = get_short_sha();
|
||||
|
||||
|
|
@ -372,10 +377,10 @@ fn create_rollout_tag(rollout_job: &NamedJob, filter_repos_input: &WorkflowInput
|
|||
}
|
||||
|
||||
let (authenticate, token) =
|
||||
generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY).for_repository(
|
||||
RepositoryTarget::current()
|
||||
.permissions([("permission-contents".to_owned(), Level::Write)]),
|
||||
);
|
||||
generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY)
|
||||
.for_repository(RepositoryTarget::current())
|
||||
.with_permissions([(TokenPermissions::Contents, Level::Write)])
|
||||
.into();
|
||||
|
||||
let job = Job::default()
|
||||
.needs([rollout_job.name.clone()])
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ fn update_sha_in_extensions(publish_job: &NamedJob) -> NamedJob {
|
|||
let extensions_repo = RepositoryTarget::new("zed-industries", &["extensions"]);
|
||||
let (generate_token, generated_token) =
|
||||
generate_token(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY)
|
||||
.for_repository(extensions_repo);
|
||||
.for_repository(extensions_repo)
|
||||
.into();
|
||||
|
||||
fn checkout_extensions_repo(token: &StepOutput) -> Step<Use> {
|
||||
named::uses(
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ fn validate_release_assets(deps: &[&NamedJob]) -> NamedJob {
|
|||
}
|
||||
|
||||
fn auto_release_preview(deps: &[&NamedJob]) -> NamedJob {
|
||||
let (authenticate, token) = steps::authenticate_as_zippy();
|
||||
let (authenticate, token) = steps::authenticate_as_zippy().into();
|
||||
|
||||
named::job(
|
||||
dependant_job(deps)
|
||||
|
|
|
|||
|
|
@ -513,20 +513,50 @@ pub fn git_checkout(ref_name: &dyn std::fmt::Display) -> Step<Run> {
|
|||
.add_env(("REF_NAME", ref_name.to_string()))
|
||||
}
|
||||
|
||||
/// Non-exhaustive list of the permissions to be set for a GitHub app token.
|
||||
///
|
||||
/// See https://github.com/actions/create-github-app-token?tab=readme-ov-file#permission-permission-name
|
||||
/// and beyond for a full list of available permissions.
|
||||
#[allow(unused)]
|
||||
pub(crate) enum TokenPermissions {
|
||||
Contents,
|
||||
Issues,
|
||||
PullRequests,
|
||||
Workflows,
|
||||
}
|
||||
|
||||
impl TokenPermissions {
|
||||
pub fn environment_name(&self) -> &'static str {
|
||||
match self {
|
||||
TokenPermissions::Contents => "permission-contents",
|
||||
TokenPermissions::Issues => "permission-issues",
|
||||
TokenPermissions::PullRequests => "permission-pull-requests",
|
||||
TokenPermissions::Workflows => "permission-workflows",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct GenerateAppToken<'a> {
|
||||
job_name: String,
|
||||
app_id: &'a str,
|
||||
app_secret: &'a str,
|
||||
repository_target: Option<RepositoryTarget>,
|
||||
permissions: Option<Vec<(TokenPermissions, Level)>>,
|
||||
}
|
||||
|
||||
impl<'a> GenerateAppToken<'a> {
|
||||
pub fn for_repository(self, repository_target: RepositoryTarget) -> (Step<Use>, StepOutput) {
|
||||
pub fn for_repository(self, repository_target: RepositoryTarget) -> Self {
|
||||
Self {
|
||||
repository_target: Some(repository_target),
|
||||
..self
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn with_permissions(self, permissions: impl Into<Vec<(TokenPermissions, Level)>>) -> Self {
|
||||
Self {
|
||||
permissions: Some(permissions.into()),
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -549,26 +579,24 @@ impl<'a> From<GenerateAppToken<'a>> for (Step<Use>, StepOutput) {
|
|||
RepositoryTarget {
|
||||
owner,
|
||||
repositories,
|
||||
permissions,
|
||||
}| {
|
||||
input
|
||||
.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().fold(
|
||||
input,
|
||||
|input, (permission, level)| {
|
||||
input.add(
|
||||
permission,
|
||||
serde_json::to_value(&level).unwrap_or_default(),
|
||||
)
|
||||
},
|
||||
)
|
||||
})
|
||||
},
|
||||
),
|
||||
)
|
||||
.when_some(token.permissions, |input, permissions| {
|
||||
permissions
|
||||
.into_iter()
|
||||
.fold(input, |input, (permission, level)| {
|
||||
input.add(
|
||||
permission.environment_name(),
|
||||
serde_json::to_value(&level).unwrap_or_default(),
|
||||
)
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
let generated_token = StepOutput::new(&step, "token");
|
||||
|
|
@ -579,7 +607,6 @@ impl<'a> From<GenerateAppToken<'a>> for (Step<Use>, StepOutput) {
|
|||
pub(crate) struct RepositoryTarget {
|
||||
owner: Option<String>,
|
||||
repositories: Option<String>,
|
||||
permissions: Option<Vec<(String, Level)>>,
|
||||
}
|
||||
|
||||
impl RepositoryTarget {
|
||||
|
|
@ -587,7 +614,6 @@ impl RepositoryTarget {
|
|||
Self {
|
||||
owner: Some(owner.to_string()),
|
||||
repositories: Some(repositories.join("\n")),
|
||||
permissions: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -595,14 +621,6 @@ impl RepositoryTarget {
|
|||
Self {
|
||||
owner: None,
|
||||
repositories: None,
|
||||
permissions: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn permissions(self, permissions: impl Into<Vec<(String, Level)>>) -> Self {
|
||||
Self {
|
||||
permissions: Some(permissions.into()),
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -614,8 +632,8 @@ pub(crate) fn generate_token<'a>(
|
|||
generate_token_with_job_name(app_id_source, app_secret_source)
|
||||
}
|
||||
|
||||
pub fn authenticate_as_zippy() -> (Step<Use>, StepOutput) {
|
||||
generate_token_with_job_name(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY).into()
|
||||
pub fn authenticate_as_zippy() -> GenerateAppToken<'static> {
|
||||
generate_token_with_job_name(vars::ZED_ZIPPY_APP_ID, vars::ZED_ZIPPY_APP_PRIVATE_KEY)
|
||||
}
|
||||
|
||||
fn generate_token_with_job_name<'a>(
|
||||
|
|
@ -627,5 +645,6 @@ fn generate_token_with_job_name<'a>(
|
|||
app_id: app_id_source,
|
||||
app_secret: app_secret_source,
|
||||
repository_target: None,
|
||||
permissions: None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue