From 10fb22726b2f8070df1fc99eae20e0eef2457665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?McKayla=20=E3=81=AF=E3=81=AA?= Date: Thu, 8 Oct 2026 21:28:46 +0000 Subject: [PATCH 1/2] docs: add release and provisioning profile instructions --- CONTRIBUTING.md | 3 +++ RELEASING.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 RELEASING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5a9abca8..a64d63cd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -144,5 +144,8 @@ To maintain code quality, ensure you run the following before submitting any cha 4. Open a pull request to the main repository. +Maintainers can find release and signing instructions in +[RELEASING.md](RELEASING.md). + Thank you for contributing! If you have any questions or need further assistance, feel free to open an issue. diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 00000000..609d3786 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,58 @@ +# Releasing Coder Desktop + +These tasks require access to Coder's Apple Developer team and admin access to +this repository. + +## Releasing a new version + +Versions come from Git tags of the form `vX.Y.Z` (see `scripts/version.sh`). +Pushing a tag doesn't start a workflow, but the GitHub release needs a tag to +point at. + +1. Tag the commit on `main` that you want to release, and push the tag: + + ```bash + git tag vX.Y.Z + git push origin vX.Y.Z + ``` + +2. Wait for the `release` workflow run for that commit on `main` to finish. + It publishes the `preview` build and updates the appcast, so publishing the + release while it is still running can race on the appcast update. +3. [Create a GitHub release](https://github.com/coder/coder-desktop-macos/releases/new) + from the tag and write the release notes. The release notes are used as the + update description in the Sparkle appcast, so write them before publishing. +4. Publishing the release starts the `release` workflow, which builds, signs, + and notarizes the app, uploads the assets to the release, updates the + appcast, and opens a pull request to update the + [homebrew-coder](https://github.com/coder/homebrew-coder) cask. Wait for it + to finish, then review and merge the cask pull request. + +## Updating provisioning profiles + +Release builds are signed with two provisioning profiles, one for the app +(`com.coder.Coder-Desktop`) and one for the network extension +(`com.coder.Coder-Desktop.VPN`). CI reads them from these repository secrets: + +| Secret | Profile | +| ---------------------------------------------- | ----------------- | +| `CODER_DESKTOP_APP_PROVISIONPROFILE_B64` | App | +| `CODER_DESKTOP_EXTENSION_PROVISIONPROFILE_B64` | Network extension | + +When a profile expires or needs regenerating: + +1. Sign in to the [Apple Developer portal](https://developer.apple.com/account/resources/profiles/list) + and open **Certificates, Identifiers & Profiles** > **Profiles**. +2. Regenerate or edit the profile if needed, then download it. +3. Base64-encode the downloaded file and copy the output: + + ```bash + cat Coder_Desktop_.provisionprofile | base64 + ``` + +4. Paste the output into the matching secret under **Settings** > + **Secrets and variables** > **Actions**. + +To check new profiles before cutting a release, run the `release` workflow +manually with **dryrun** enabled. The build is uploaded as a workflow artifact +instead of a release asset. From 3f12727504e3e37af429ac634faf527573f00974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?McKayla=20=E3=81=AF=E3=81=AA?= Date: Thu, 8 Oct 2026 21:29:50 +0000 Subject: [PATCH 2/2] docs: use actual provisioning profile filenames --- RELEASING.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 609d3786..650da52b 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -34,10 +34,10 @@ Release builds are signed with two provisioning profiles, one for the app (`com.coder.Coder-Desktop`) and one for the network extension (`com.coder.Coder-Desktop.VPN`). CI reads them from these repository secrets: -| Secret | Profile | -| ---------------------------------------------- | ----------------- | -| `CODER_DESKTOP_APP_PROVISIONPROFILE_B64` | App | -| `CODER_DESKTOP_EXTENSION_PROVISIONPROFILE_B64` | Network extension | +| Secret | Profile file | +| ---------------------------------------------- | ------------------------------------------ | +| `CODER_DESKTOP_APP_PROVISIONPROFILE_B64` | `Coder_Desktop_App.provisionprofile` | +| `CODER_DESKTOP_EXTENSION_PROVISIONPROFILE_B64` | `Coder_Desktop_Extension.provisionprofile` | When a profile expires or needs regenerating: @@ -47,7 +47,8 @@ When a profile expires or needs regenerating: 3. Base64-encode the downloaded file and copy the output: ```bash - cat Coder_Desktop_.provisionprofile | base64 + cat Coder_Desktop_App.provisionprofile | base64 + cat Coder_Desktop_Extension.provisionprofile | base64 ``` 4. Paste the output into the matching secret under **Settings** >