Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,22 @@ jobs:
command: |
set -euo pipefail
circleci run release update "release-<< pipeline.git.tag >>" --status=FAILED
- run:
name: Sync Linear release
when: on_success
command: |
set -uo pipefail
# set -e is suspended on the left side of `||`, so chain commands
# with `&&` to short-circuit on the first failure and let the
# group's exit code reflect the actual outcome.
{ ./scripts/download-linear-release.sh \
&& git fetch --force --tags origin \
&& /tmp/linear-release sync \
--release-version="<< pipeline.git.tag >>" \
&& /tmp/linear-release update \
--release-version="<< pipeline.git.tag >>" \
--stage="Started"
} || echo "Linear release sync failed; artifact published. Sync manually if needed."

# ------------------------------------------------------------
# WORKFLOWS
Expand Down Expand Up @@ -428,6 +444,8 @@ workflows:
- publish-build-artifact:
<<: *tag-filter
name: publish release artifact
context: aws-dev
context:
- aws-dev
- linear-secrets
requires:
- build
49 changes: 48 additions & 1 deletion .circleci/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,18 +253,64 @@ jobs:
}
]
}
- run:
name: Update Linear release stage
when: on_success
command: |
set -uo pipefail
Comment thread
paulfalgout marked this conversation as resolved.

case "$DEPLOY_STAGE" in
qa) linear_stage="QA" ;;
sandbox) linear_stage="Sandbox" ;;
prod)
# Only the wildcard prod:* deploy represents a real release
# event. Org-scoped prod deploys (e.g. prod:demonstration,
# prod:apple) must not advance or complete the Linear release.
if [ -n "$DEPLOY_ORGANIZATION" ]; then
echo "Skipping Linear release update for prod:$DEPLOY_ORGANIZATION"
exit 0
fi
linear_stage="Released"
;;
*) exit 0 ;;
esac

# set -e is suspended on the left side of `||`, so chain commands
# with `&&` to short-circuit on the first failure and let the
# group's exit code reflect the actual outcome.
{ ./scripts/download-linear-release.sh \
&& git fetch --force --tags origin \
&& /tmp/linear-release update \
--release-version="$DEPLOY_TARGET_VERSION" \
--stage="$linear_stage" \
&& { [ "$DEPLOY_STAGE" != "prod" ] \
|| /tmp/linear-release complete \
--release-version="$DEPLOY_TARGET_VERSION"; }
} || echo "Linear release update failed; deploy succeeded. Sync manually if needed."

workflows:
deploy-dev:
when:
matches:
pattern: '^(dev|qa):[a-z0-9*-]+$'
pattern: '^dev:[a-z0-9*-]+$'
value: << pipeline.deploy.environment_name >>
jobs:
- deploy-from-artifact:
context:
- aws-dev
- slack-secrets

deploy-qa:
when:
matches:
pattern: '^qa:[a-z0-9*-]+$'
value: << pipeline.deploy.environment_name >>
jobs:
- deploy-from-artifact:
context:
- aws-dev
- slack-secrets
- linear-secrets

deploy-prod:
when:
Expand All @@ -276,3 +322,4 @@ workflows:
context:
- aws-prod
- slack-secrets
- linear-secrets
12 changes: 12 additions & 0 deletions docs/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ npm run deploy -- --stage=<stage> [--organization=<organization>]
- stage-wide deploys continue through every resolved environment and fail the job at the end if any targets fail
- if a stage-wide deploy partially succeeds, concrete environment markers reflect the per-environment outcomes while the wildcard marker reflects the overall deploy result
6. For QA deploys that include `qa2` (`qa:qa2` and `qa:*`), posts `qa2_deploy_succeeded` to `RoundingWell/app-tests`
7. Updates the Linear release stage by running the pinned `linear/linear-release` CLI (downloaded by [`scripts/download-linear-release.sh`](../scripts/download-linear-release.sh)):
- `qa:*` and specific `qa:<organization>` deploys → `update --stage=QA`
- `sandbox:*` and specific `sandbox:<organization>` deploys → `update --stage=Sandbox`
- `prod:*` (wildcard only) → `update --stage=Released`, then `complete`
- org-scoped `prod:<organization>` deploys (e.g. `prod:demonstration`, `prod:apple`) are skipped — only the wildcard prod deploy represents a release event
- `dev` deploys are skipped
- the step is failure-tolerant (`|| echo …`); a Linear API or download failure does not fail the deploy job

Supported deploy environments:
- `dev:<organization>`
Expand Down Expand Up @@ -167,6 +174,11 @@ Additional CircleCI secrets for the QA2 E2E dispatch step:
- `GH_APP_PRIVATE_KEY`
- `GH_APP_INSTALLATION_ID`

CircleCI context for the Linear release steps:
- `linear-secrets` context, providing `LINEAR_ACCESS_KEY` (Linear release pipeline access key)
- attached to the `release-artifact` workflow in [`.circleci/config.yml`](../.circleci/config.yml) (sync + `Started` stage on tag build), and to the `deploy-qa` and `deploy-prod` workflows in [`.circleci/deploy.yml`](../.circleci/deploy.yml). The `deploy-dev` workflow does not have access to the Linear secret.
- the Linear release pipeline is configured as **scheduled**; stages used: built-in `Started`, custom `QA` (frozen) and `Sandbox`, and built-in terminal `Released`. CI also calls `complete` after a successful prod deploy.

For QA deploys that include `qa2`, [`.circleci/deploy.yml`](../.circleci/deploy.yml) resolves the release SHA, passes the release tag, SHA, and a CircleCI run URL to [`scripts/dispatch-qa2-e2e.js`](../scripts/dispatch-qa2-e2e.js), and that script uses the GitHub App credentials above plus the `app-tests` installation id to mint a short-lived installation token before posting `repository_dispatch` with this payload:

```json
Expand Down
17 changes: 17 additions & 0 deletions scripts/download-linear-release.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Download and verify the linear/linear-release CLI to /tmp/linear-release.
# Single source of truth for the pinned version + sha256 used by both
# .circleci/config.yml (release-artifact workflow) and .circleci/deploy.yml
# (deploy workflows). Prints the binary path on success.

set -euo pipefail

linear_release_version="v0.7.0"
linear_release_sha256="c82e10e79ac54bfa5efff69124add2aa793d91b0d5e32c1ed56ab856eb2a7e79"
linear_release_url="https://github.com/linear/linear-release/releases/download/${linear_release_version}/linear-release-linux-x64"
linear_release_bin="${LINEAR_RELEASE_BIN:-/tmp/linear-release}"

curl -fsSL "$linear_release_url" -o "$linear_release_bin"
echo "${linear_release_sha256} ${linear_release_bin}" | sha256sum -c -
chmod +x "$linear_release_bin"
echo "$linear_release_bin"
Loading