This PR updates the Collab deployment workflow to be generated with `cargo xtask workflows`. Release Notes: - N/A
Showing the changes to tooling (3 of 4 files). Show all
Unified · Split
| @@ -10,6 +10,7 @@ mod bump_patch_version; · 9 unmodified lines | |||
| 10 | mod cherry_pick; | 10 | mod cherry_pick; |
| 11 | mod compare_perf; | 11 | mod compare_perf; |
| 12 | mod danger; | 12 | mod danger; |
| 13 | mod deploy_collab; | ||
| 13 | mod extension_bump; | 14 | mod extension_bump; |
| 14 | mod extension_tests; | 15 | mod extension_tests; |
| 15 | mod extension_workflow_rollout; | 16 | mod extension_workflow_rollout; |
| @@ -133,6 +134,7 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { · 117 unmodified lines | |||
| 133 | WorkflowFile::zed(cherry_pick::cherry_pick), | 134 | WorkflowFile::zed(cherry_pick::cherry_pick), |
| 134 | WorkflowFile::zed(compare_perf::compare_perf), | 135 | WorkflowFile::zed(compare_perf::compare_perf), |
| 135 | WorkflowFile::zed(danger::danger), | 136 | WorkflowFile::zed(danger::danger), |
| 137 | WorkflowFile::zed(deploy_collab::deploy_collab), | ||
| 136 | WorkflowFile::zed(extension_bump::extension_bump), | 138 | WorkflowFile::zed(extension_bump::extension_bump), |
| 137 | WorkflowFile::zed(extension_tests::extension_tests), | 139 | WorkflowFile::zed(extension_tests::extension_tests), |
| 138 | WorkflowFile::zed(extension_workflow_rollout::extension_workflow_rollout), | 140 | WorkflowFile::zed(extension_workflow_rollout::extension_workflow_rollout), |
| @@ -0,0 +1,171 @@ | |||
| 1 | use gh_workflow::{Container, Event, Port, Push, Run, Step, Use, Workflow}; | ||
| 2 | use indoc::{formatdoc, indoc}; | ||
| 3 | |||
| 4 | use crate::tasks::workflows::{ | ||
| 5 | runners::{self, Platform}, | ||
| 6 | steps::{self, CommonJobConditions, NamedJob, dependant_job, named}, | ||
| 7 | vars, | ||
| 8 | }; | ||
| 9 | |||
| 10 | pub(crate) fn deploy_collab() -> Workflow { | ||
| 11 | let style = style(); | ||
| 12 | let tests = tests(&[&style]); | ||
| 13 | let publish = publish(&[&style, &tests]); | ||
| 14 | let deploy = deploy(&[&publish]); | ||
| 15 | |||
| 16 | named::workflow() | ||
| 17 | .on(Event::default().push(Push::default().add_tag("collab-production"))) | ||
| 18 | .add_env(("DOCKER_BUILDKIT", "1")) | ||
| 19 | .add_job(style.name, style.job) | ||
| 20 | .add_job(tests.name, tests.job) | ||
| 21 | .add_job(publish.name, publish.job) | ||
| 22 | .add_job(deploy.name, deploy.job) | ||
| 23 | } | ||
| 24 | |||
| 25 | fn style() -> NamedJob { | ||
| 26 | named::job( | ||
| 27 | dependant_job(&[]) | ||
| 28 | .name("Check formatting and Clippy lints") | ||
| 29 | .with_repository_owner_guard() | ||
| 30 | .runs_on(runners::LINUX_XL) | ||
| 31 | .add_step(steps::checkout_repo().add_with(("fetch-depth", 0))) | ||
| 32 | .add_step(steps::setup_cargo_config(Platform::Linux)) | ||
| 33 | .add_step(steps::cache_rust_dependencies_namespace()) | ||
| 34 | .add_step(steps::cargo_fmt()) | ||
| 35 | .add_step(steps::clippy(Platform::Linux)), | ||
| 36 | ) | ||
| 37 | } | ||
| 38 | |||
| 39 | fn tests(deps: &[&NamedJob]) -> NamedJob { | ||
| 40 | fn run_collab_tests() -> Step<Run> { | ||
| 41 | named::bash("cargo nextest run --package collab --no-fail-fast") | ||
| 42 | } | ||
| 43 | |||
| 44 | named::job( | ||
| 45 | dependant_job(deps) | ||
| 46 | .name("Run tests") | ||
| 47 | .runs_on(runners::LINUX_XL) | ||
| 48 | .add_service( | ||
| 49 | "postgres", | ||
| 50 | Container::new("postgres:15") | ||
| 51 | .add_env(("POSTGRES_HOST_AUTH_METHOD", "trust")) | ||
| 52 | .ports(vec![Port::Name("5432:5432".into())]) | ||
| 53 | .options( | ||
| 54 | "--health-cmd pg_isready \ | ||
| 55 | --health-interval 500ms \ | ||
| 56 | --health-timeout 5s \ | ||
| 57 | --health-retries 10", | ||
| 58 | ), | ||
| 59 | ) | ||
| 60 | .add_step(steps::checkout_repo().add_with(("fetch-depth", 0))) | ||
| 61 | .add_step(steps::setup_cargo_config(Platform::Linux)) | ||
| 62 | .add_step(steps::cache_rust_dependencies_namespace()) | ||
| 63 | .add_step(steps::cargo_install_nextest()) | ||
| 64 | .add_step(steps::clear_target_dir_if_large(Platform::Linux)) | ||
| 65 | .add_step(run_collab_tests()), | ||
| 66 | ) | ||
| 67 | } | ||
| 68 | |||
| 69 | fn publish(deps: &[&NamedJob]) -> NamedJob { | ||
| 70 | fn install_doctl() -> Step<Use> { | ||
| 71 | named::uses("digitalocean", "action-doctl", "v2") | ||
| 72 | .add_with(("token", vars::DIGITALOCEAN_ACCESS_TOKEN)) | ||
| 73 | } | ||
| 74 | |||
| 75 | fn sign_into_registry() -> Step<Run> { | ||
| 76 | named::bash("doctl registry login") | ||
| 77 | } | ||
| 78 | |||
| 79 | fn build_docker_image() -> Step<Run> { | ||
| 80 | named::bash(indoc! {r#" | ||
| 81 | docker build -f Dockerfile-collab \ | ||
| 82 | --build-arg "GITHUB_SHA=$GITHUB_SHA" \ | ||
| 83 | --tag "registry.digitalocean.com/zed/collab:$GITHUB_SHA" \ | ||
| 84 | . | ||
| 85 | "#}) | ||
| 86 | } | ||
| 87 | |||
| 88 | fn publish_docker_image() -> Step<Run> { | ||
| 89 | named::bash(r#"docker push "registry.digitalocean.com/zed/collab:${GITHUB_SHA}""#) | ||
| 90 | } | ||
| 91 | |||
| 92 | fn prune_docker_system() -> Step<Run> { | ||
| 93 | named::bash("docker system prune --filter 'until=72h' -f") | ||
| 94 | } | ||
| 95 | |||
| 96 | named::job( | ||
| 97 | dependant_job(deps) | ||
| 98 | .name("Publish collab server image") | ||
| 99 | .runs_on(runners::LINUX_XL) | ||
| 100 | .add_step(install_doctl()) | ||
| 101 | .add_step(sign_into_registry()) | ||
| 102 | .add_step(steps::checkout_repo()) | ||
| 103 | .add_step(build_docker_image()) | ||
| 104 | .add_step(publish_docker_image()) | ||
| 105 | .add_step(prune_docker_system()), | ||
| 106 | ) | ||
| 107 | } | ||
| 108 | |||
| 109 | fn deploy(deps: &[&NamedJob]) -> NamedJob { | ||
| 110 | fn install_doctl() -> Step<Use> { | ||
| 111 | named::uses("digitalocean", "action-doctl", "v2") | ||
| 112 | .add_with(("token", vars::DIGITALOCEAN_ACCESS_TOKEN)) | ||
| 113 | } | ||
| 114 | |||
| 115 | fn sign_into_kubernetes() -> Step<Run> { | ||
| 116 | named::bash(formatdoc! {r#" | ||
| 117 | doctl kubernetes cluster kubeconfig save --expiry-seconds 600 {cluster_name} | ||
| 118 | "#, cluster_name = vars::CLUSTER_NAME}) | ||
| 119 | } | ||
| 120 | |||
| 121 | fn start_rollout() -> Step<Run> { | ||
| 122 | named::bash(indoc! {r#" | ||
| 123 | set -eu | ||
| 124 | if [[ $GITHUB_REF_NAME = "collab-production" ]]; then | ||
| 125 | export ZED_KUBE_NAMESPACE=production | ||
| 126 | export ZED_COLLAB_LOAD_BALANCER_SIZE_UNIT=10 | ||
| 127 | export ZED_API_LOAD_BALANCER_SIZE_UNIT=2 | ||
| 128 | elif [[ $GITHUB_REF_NAME = "collab-staging" ]]; then | ||
| 129 | export ZED_KUBE_NAMESPACE=staging | ||
| 130 | export ZED_COLLAB_LOAD_BALANCER_SIZE_UNIT=1 | ||
| 131 | export ZED_API_LOAD_BALANCER_SIZE_UNIT=1 | ||
| 132 | else | ||
| 133 | echo "cowardly refusing to deploy from an unknown branch" | ||
| 134 | exit 1 | ||
| 135 | fi | ||
| 136 | |||
| 137 | echo "Deploying collab:$GITHUB_SHA to $ZED_KUBE_NAMESPACE" | ||
| 138 | |||
| 139 | source script/lib/deploy-helpers.sh | ||
| 140 | export_vars_for_environment $ZED_KUBE_NAMESPACE | ||
| 141 | |||
| 142 | ZED_DO_CERTIFICATE_ID="$(doctl compute certificate list --format ID --no-header)" | ||
| 143 | export ZED_DO_CERTIFICATE_ID | ||
| 144 | export ZED_IMAGE_ID="registry.digitalocean.com/zed/collab:${GITHUB_SHA}" | ||
| 145 | |||
| 146 | export ZED_SERVICE_NAME=collab | ||
| 147 | export ZED_LOAD_BALANCER_SIZE_UNIT=$ZED_COLLAB_LOAD_BALANCER_SIZE_UNIT | ||
| 148 | export DATABASE_MAX_CONNECTIONS=850 | ||
| 149 | envsubst < crates/collab/k8s/collab.template.yml | kubectl apply -f - | ||
| 150 | kubectl -n "$ZED_KUBE_NAMESPACE" rollout status deployment/$ZED_SERVICE_NAME --watch | ||
| 151 | echo "deployed ${ZED_SERVICE_NAME} to ${ZED_KUBE_NAMESPACE}" | ||
| 152 | |||
| 153 | export ZED_SERVICE_NAME=api | ||
| 154 | export ZED_LOAD_BALANCER_SIZE_UNIT=$ZED_API_LOAD_BALANCER_SIZE_UNIT | ||
| 155 | export DATABASE_MAX_CONNECTIONS=60 | ||
| 156 | envsubst < crates/collab/k8s/collab.template.yml | kubectl apply -f - | ||
| 157 | kubectl -n "$ZED_KUBE_NAMESPACE" rollout status deployment/$ZED_SERVICE_NAME --watch | ||
| 158 | echo "deployed ${ZED_SERVICE_NAME} to ${ZED_KUBE_NAMESPACE}" | ||
| 159 | "#}) | ||
| 160 | } | ||
| 161 | |||
| 162 | named::job( | ||
| 163 | dependant_job(deps) | ||
| 164 | .name("Deploy new server image") | ||
| 165 | .runs_on(runners::LINUX_XL) | ||
| 166 | .add_step(steps::checkout_repo()) | ||
| 167 | .add_step(install_doctl()) | ||
| 168 | .add_step(sign_into_kubernetes()) | ||
| 169 | .add_step(start_rollout()), | ||
| 170 | ) | ||
| 171 | } | ||
| @@ -30,6 +30,8 @@ secret!(AZURE_SIGNING_CLIENT_ID); · 29 unmodified lines | |||
| 30 | secret!(AZURE_SIGNING_CLIENT_SECRET); | 30 | secret!(AZURE_SIGNING_CLIENT_SECRET); |
| 31 | secret!(AZURE_SIGNING_TENANT_ID); | 31 | secret!(AZURE_SIGNING_TENANT_ID); |
| 32 | secret!(CACHIX_AUTH_TOKEN); | 32 | secret!(CACHIX_AUTH_TOKEN); |
| 33 | secret!(CLUSTER_NAME); | ||
| 34 | secret!(DIGITALOCEAN_ACCESS_TOKEN); | ||
| 33 | secret!(DIGITALOCEAN_SPACES_ACCESS_KEY); | 35 | secret!(DIGITALOCEAN_SPACES_ACCESS_KEY); |
| 34 | secret!(DIGITALOCEAN_SPACES_SECRET_KEY); | 36 | secret!(DIGITALOCEAN_SPACES_SECRET_KEY); |
| 35 | secret!(GITHUB_TOKEN); | 37 | secret!(GITHUB_TOKEN); |