44push :
55branches :
66 -main
7+ -release/*
78
89pull_request :
910workflow_dispatch :
@@ -969,7 +970,7 @@ jobs:
969970needs :changes
970971# We always build the dylibs on Go changes to verify we're not merging unbuildable code,
971972# but they need only be signed and uploaded on coder/coder main.
972- if :needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
973+ if :needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
973974runs-on :${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest' }}
974975steps :
975976# Harden Runner doesn't work on macOS
@@ -997,7 +998,7 @@ jobs:
997998uses :./.github/actions/setup-go
998999
9991000 -name :Install rcodesign
1000- if :${{ github.repository_owner == 'coder' && github.ref == 'refs/heads/main' }}
1001+ if :${{ github.repository_owner == 'coder' &&( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) }}
10011002run :|
10021003 set -euo pipefail
10031004 wget -O /tmp/rcodesign.tar.gz https://github.com/indygreg/apple-platform-rs/releases/download/apple-codesign%2F0.22.0/apple-codesign-0.22.0-macos-universal.tar.gz
@@ -1008,7 +1009,7 @@ jobs:
10081009 rm /tmp/rcodesign.tar.gz
10091010
10101011 -name :Setup Apple Developer certificate and API key
1011- if :${{ github.repository_owner == 'coder' && github.ref == 'refs/heads/main' }}
1012+ if :${{ github.repository_owner == 'coder' &&( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) }}
10121013run :|
10131014 set -euo pipefail
10141015 touch /tmp/{apple_cert.p12,apple_cert_password.txt,apple_apikey.p8}
@@ -1029,12 +1030,12 @@ jobs:
10291030 make gen/mark-fresh
10301031 make build/coder-dylib
10311032env :
1032- CODER_SIGN_DARWIN :${{ github.ref == 'refs/heads/main' && '1' || '0' }}
1033+ CODER_SIGN_DARWIN :${{( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && '1' || '0' }}
10331034AC_CERTIFICATE_FILE :/tmp/apple_cert.p12
10341035AC_CERTIFICATE_PASSWORD_FILE :/tmp/apple_cert_password.txt
10351036
10361037 -name :Upload build artifacts
1037- if :${{ github.repository_owner == 'coder' && github.ref == 'refs/heads/main' }}
1038+ if :${{ github.repository_owner == 'coder' &&( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) }}
10381039uses :actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
10391040with :
10401041name :dylibs
@@ -1044,7 +1045,7 @@ jobs:
10441045retention-days :7
10451046
10461047 -name :Delete Apple Developer certificate and API key
1047- if :${{ github.repository_owner == 'coder' && github.ref == 'refs/heads/main' }}
1048+ if :${{ github.repository_owner == 'coder' &&( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) }}
10481049run :rm -f /tmp/{apple_cert.p12,apple_cert_password.txt,apple_apikey.p8}
10491050
10501051check-build :
@@ -1094,7 +1095,7 @@ jobs:
10941095needs :
10951096 -changes
10961097 -build-dylib
1097- if :github.ref == 'refs/heads/main' && needs.changes.outputs.docs-only == 'false' && !github.event.pull_request.head.repo.fork
1098+ if :( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && needs.changes.outputs.docs-only == 'false' && !github.event.pull_request.head.repo.fork
10981099runs-on :${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-22.04' }}
10991100permissions :
11001101# Necessary to push docker images to ghcr.io.
@@ -1247,40 +1248,45 @@ jobs:
12471248id :build-docker
12481249env :
12491250CODER_IMAGE_BASE :ghcr.io/coder/coder-preview
1250- CODER_IMAGE_TAG_PREFIX :main
12511251DOCKER_CLI_EXPERIMENTAL :" enabled"
12521252run :|
12531253 set -euxo pipefail
12541254
12551255 # build Docker images for each architecture
12561256 version="$(./scripts/version.sh)"
1257- tag="main- ${version//+/-}"
1257+ tag="${version//+/-}"
12581258 echo "tag=$tag" >> "$GITHUB_OUTPUT"
12591259
12601260 # build images for each architecture
12611261 # note: omitting the -j argument to avoid race conditions when pushing
12621262 make build/coder_"$version"_linux_{amd64,arm64,armv7}.tag
12631263
1264- # only push if we are on main branch
1265- if [ "${GITHUB_REF}" == "refs/heads/main" ]; then
1264+ # only push if we are on main branch or release branch
1265+ if [[ "${GITHUB_REF}" == "refs/heads/main"|| "${GITHUB_REF}" == refs/heads/release/* ] ]; then
12661266 # build and push multi-arch manifest, this depends on the other images
12671267 # being pushed so will automatically push them
12681268 # note: omitting the -j argument to avoid race conditions when pushing
12691269 make push/build/coder_"$version"_linux_{amd64,arm64,armv7}.tag
12701270
12711271 # Define specific tags
1272- tags=("$tag" "main" "latest")
1272+ tags=("$tag")
1273+ if [ "${GITHUB_REF}" == "refs/heads/main" ]; then
1274+ tags+=("main" "latest")
1275+ elif [[ "${GITHUB_REF}" == refs/heads/release/* ]]; then
1276+ tags+=("release-${GITHUB_REF#refs/heads/release/}")
1277+ fi
12731278
12741279 # Create and push a multi-arch manifest for each tag
12751280 # we are adding `latest` tag and keeping `main` for backward
12761281 # compatibality
12771282 for t in "${tags[@]}"; do
1278- # shellcheck disable=SC2046
1279- ./scripts/build_docker_multiarch.sh \
1280- --push \
1281- --target "ghcr.io/coder/coder-preview:$t" \
1282- --version "$version" \
1283- $(cat build/coder_"$version"_linux_{amd64,arm64,armv7}.tag)
1283+ echo "Pushing multi-arch manifest for tag: $t"
1284+ # shellcheck disable=SC2046
1285+ ./scripts/build_docker_multiarch.sh \
1286+ --push \
1287+ --target "ghcr.io/coder/coder-preview:$t" \
1288+ --version "$version" \
1289+ $(cat build/coder_"$version"_linux_{amd64,arm64,armv7}.tag)
12841290 done
12851291 fi
12861292
@@ -1471,112 +1477,28 @@ jobs:
14711477 ./build/*.deb
14721478retention-days :7
14731479
1480+ # Deploy is handled in deploy.yaml so we can apply concurrency limits.
14741481deploy :
1475- name :" deploy"
1476- runs-on :ubuntu-latest
1477- timeout-minutes :30
14781482needs :
14791483 -changes
14801484 -build
14811485if :|
1482- github.ref == 'refs/heads/main'&& ! github.event.pull_request.head.repo.fork
1486+ ( github.ref == 'refs/heads/main'|| startsWith( github.ref, 'refs/heads/release/'))
14831487 && needs.changes.outputs.docs-only == 'false'
1488+ && !github.event.pull_request.head.repo.fork
1489+ uses :./.github/workflows/deploy.yaml
1490+ with :
1491+ image :${{ needs.build.outputs.IMAGE }}
14841492permissions :
14851493contents :read
14861494id-token :write
1487- steps :
1488- -name :Harden Runner
1489- uses :step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
1490- with :
1491- egress-policy :audit
1492-
1493- -name :Checkout
1494- uses :actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
1495- with :
1496- fetch-depth :0
1497- persist-credentials :false
1498-
1499- -name :Authenticate to Google Cloud
1500- uses :google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
1501- with :
1502- workload_identity_provider :${{ vars.GCP_WORKLOAD_ID_PROVIDER }}
1503- service_account :${{ vars.GCP_SERVICE_ACCOUNT }}
1504-
1505- -name :Set up Google Cloud SDK
1506- uses :google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1
1507-
1508- -name :Set up Flux CLI
1509- uses :fluxcd/flux2/action@6bf37f6a560fd84982d67f853162e4b3c2235edb # v2.6.4
1510- with :
1511- # Keep this and the github action up to date with the version of flux installed in dogfood cluster
1512- version :" 2.5.1"
1513-
1514- -name :Get Cluster Credentials
1515- uses :google-github-actions/get-gke-credentials@3da1e46a907576cefaa90c484278bb5b259dd395 # v3.0.0
1516- with :
1517- cluster_name :dogfood-v2
1518- location :us-central1-a
1519- project_id :coder-dogfood-v2
1520-
1521- -name :Reconcile Flux
1522- run :|
1523- set -euxo pipefail
1524- flux --namespace flux-system reconcile source git flux-system
1525- flux --namespace flux-system reconcile source git coder-main
1526- flux --namespace flux-system reconcile kustomization flux-system
1527- flux --namespace flux-system reconcile kustomization coder
1528- flux --namespace flux-system reconcile source chart coder-coder
1529- flux --namespace flux-system reconcile source chart coder-coder-provisioner
1530- flux --namespace coder reconcile helmrelease coder
1531- flux --namespace coder reconcile helmrelease coder-provisioner
1532-
1533- # Just updating Flux is usually not enough. The Helm release may get
1534- # redeployed, but unless something causes the Deployment to update the
1535- # pods won't be recreated. It's important that the pods get recreated,
1536- # since we use `imagePullPolicy: Always` to ensure we're running the
1537- # latest image.
1538- -name :Rollout Deployment
1539- run :|
1540- set -euxo pipefail
1541- kubectl --namespace coder rollout restart deployment/coder
1542- kubectl --namespace coder rollout status deployment/coder
1543- kubectl --namespace coder rollout restart deployment/coder-provisioner
1544- kubectl --namespace coder rollout status deployment/coder-provisioner
1545- kubectl --namespace coder rollout restart deployment/coder-provisioner-tagged
1546- kubectl --namespace coder rollout status deployment/coder-provisioner-tagged
1547-
1548- deploy-wsproxies :
1549- runs-on :ubuntu-latest
1550- needs :build
1551- if :github.ref == 'refs/heads/main' && !github.event.pull_request.head.repo.fork
1552- steps :
1553- -name :Harden Runner
1554- uses :step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
1555- with :
1556- egress-policy :audit
1557-
1558- -name :Checkout
1559- uses :actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
1560- with :
1561- fetch-depth :0
1562- persist-credentials :false
1563-
1564- -name :Setup flyctl
1565- uses :superfly/flyctl-actions/setup-flyctl@fc53c09e1bc3be6f54706524e3b82c4f462f77be # v1.5
1566-
1567- -name :Deploy workspace proxies
1568- run :|
1569- flyctl deploy --image "$IMAGE" --app paris-coder --config ./.github/fly-wsproxies/paris-coder.toml --env "CODER_PROXY_SESSION_TOKEN=$TOKEN_PARIS" --yes
1570- flyctl deploy --image "$IMAGE" --app sydney-coder --config ./.github/fly-wsproxies/sydney-coder.toml --env "CODER_PROXY_SESSION_TOKEN=$TOKEN_SYDNEY" --yes
1571- flyctl deploy --image "$IMAGE" --app sao-paulo-coder --config ./.github/fly-wsproxies/sao-paulo-coder.toml --env "CODER_PROXY_SESSION_TOKEN=$TOKEN_SAO_PAULO" --yes
1572- flyctl deploy --image "$IMAGE" --app jnb-coder --config ./.github/fly-wsproxies/jnb-coder.toml --env "CODER_PROXY_SESSION_TOKEN=$TOKEN_JNB" --yes
1573- env :
1574- FLY_API_TOKEN :${{ secrets.FLY_API_TOKEN }}
1575- IMAGE :${{ needs.build.outputs.IMAGE }}
1576- TOKEN_PARIS :${{ secrets.FLY_PARIS_CODER_PROXY_SESSION_TOKEN }}
1577- TOKEN_SYDNEY :${{ secrets.FLY_SYDNEY_CODER_PROXY_SESSION_TOKEN }}
1578- TOKEN_SAO_PAULO :${{ secrets.FLY_SAO_PAULO_CODER_PROXY_SESSION_TOKEN }}
1579- TOKEN_JNB :${{ secrets.FLY_JNB_CODER_PROXY_SESSION_TOKEN }}
1495+ packages :write # to retag image as dogfood
1496+ secrets :
1497+ FLY_API_TOKEN :${{ secrets.FLY_API_TOKEN }}
1498+ FLY_PARIS_CODER_PROXY_SESSION_TOKEN :${{ secrets.FLY_PARIS_CODER_PROXY_SESSION_TOKEN }}
1499+ FLY_SYDNEY_CODER_PROXY_SESSION_TOKEN :${{ secrets.FLY_SYDNEY_CODER_PROXY_SESSION_TOKEN }}
1500+ FLY_SAO_PAULO_CODER_PROXY_SESSION_TOKEN :${{ secrets.FLY_SAO_PAULO_CODER_PROXY_SESSION_TOKEN }}
1501+ FLY_JNB_CODER_PROXY_SESSION_TOKEN :${{ secrets.FLY_JNB_CODER_PROXY_SESSION_TOKEN }}
15801502
15811503# sqlc-vet runs a postgres docker container, runs Coder migrations, and then
15821504# runs sqlc-vet to ensure all queries are valid. This catches any mistakes