Skip to content

Commit 5456283

Browse files
committed
chore(ci): enforce PR routing and desktop builds
1 parent 87d15f0 commit 5456283

3 files changed

Lines changed: 87 additions & 17 deletions

File tree

.github/workflows/desktop-build.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
name: desktop-build
22

33
# Internal-beta packaging: builds the desktop app for download as workflow artifacts.
4-
# Does NOT publish, version-bump, or create releases. Manual trigger only.
4+
# Does NOT publish, version-bump, or create releases.
55
#
66
# macOS signing/notarization is opt-in: if the APPLE_* / CSC_* secrets are present it
77
# signs, otherwise it builds an UNSIGNED package (testers right-click → Open to launch).
88
# Windows/Linux packages are unsigned here.
99

1010
on:
11+
push:
12+
branches:
13+
- main
1114
workflow_dispatch:
1215
inputs:
1316
channel:
1417
description: "Build channel"
1518
required: false
16-
default: "beta"
19+
default: "prod"
1720
type: choice
1821
options:
1922
- beta
@@ -33,6 +36,10 @@ permissions:
3336
contents: read
3437
actions: write
3538

39+
concurrency:
40+
group: desktop-build-${{ github.ref }}
41+
cancel-in-progress: true
42+
3643
jobs:
3744
cleanup:
3845
runs-on: ubuntu-24.04
@@ -60,13 +67,12 @@ jobs:
6067
env:
6168
PLATFORMS: ${{ github.event.inputs.platforms || 'all' }}
6269
run: |
63-
# macOS arm64 only — Apple Silicon covers current Macs. The Intel (macos-13)
70+
# Keep one artifact per OS to stay under the repo's tight artifact quota.
71+
# macOS arm64 only - Apple Silicon covers current Macs. The Intel (macos-13)
6472
# runner is queue-starved and the x64 cross-compile is unreliable, so it is dropped.
65-
mac='{"host":"macos-14","target":"mac-arm64","platform_flag":"--mac dmg --arm64","group":"mac"}'
66-
linux='{"host":"ubuntu-24.04","target":"linux-x64","platform_flag":"--linux deb rpm --x64","group":"linux"}'
67-
# Windows arm64 builds natively on the GA windows-11-arm runner (no cross-compile);
68-
# both native deps ship win32-arm64 prebuilds (@lydell/node-pty, @parcel/watcher).
69-
win='{"host":"windows-2025","target":"win-x64","platform_flag":"--win nsis --x64","group":"win"},{"host":"windows-11-arm","target":"win-arm64","platform_flag":"--win nsis --arm64","group":"win"}'
73+
mac='{"host":"macos-14","target":"darwin-arm64","platform_flag":"--mac dmg --arm64","group":"mac"}'
74+
linux='{"host":"ubuntu-24.04","target":"linux-amd64","platform_flag":"--linux deb --x64","group":"linux"}'
75+
win='{"host":"windows-2025","target":"win-x64","platform_flag":"--win nsis --x64","group":"win"}'
7076
case "$PLATFORMS" in
7177
mac) items="$mac" ;;
7278
linux) items="$linux" ;;
@@ -101,11 +107,6 @@ jobs:
101107
with:
102108
node-version: "24"
103109

104-
# rpm tooling for the Linux rpm target (deb needs no extra tools).
105-
- name: Install rpm (linux)
106-
if: matrix.group == 'linux'
107-
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends rpm
108-
109110
# Import the Developer ID cert only when the secret is configured; otherwise the
110111
# build proceeds unsigned (DEEPAGENT_CODE_ALLOW_UNSIGNED below).
111112
- name: Import Apple signing certificate
@@ -118,20 +119,20 @@ jobs:
118119
- name: Prebuild
119120
working-directory: packages/desktop
120121
env:
121-
DEEPAGENT_CODE_CHANNEL: ${{ github.event.inputs.channel || 'beta' }}
122+
DEEPAGENT_CODE_CHANNEL: ${{ github.event_name == 'push' && 'prod' || (github.event.inputs.channel || 'prod') }}
122123
run: bun run prebuild
123124

124125
- name: Build renderer
125126
working-directory: packages/desktop
126127
env:
127-
DEEPAGENT_CODE_CHANNEL: ${{ github.event.inputs.channel || 'beta' }}
128+
DEEPAGENT_CODE_CHANNEL: ${{ github.event_name == 'push' && 'prod' || (github.event.inputs.channel || 'prod') }}
128129
run: bun run build
129130

130131
- name: Package
131132
working-directory: packages/desktop
132133
timeout-minutes: 60
133134
env:
134-
DEEPAGENT_CODE_CHANNEL: ${{ github.event.inputs.channel || 'beta' }}
135+
DEEPAGENT_CODE_CHANNEL: ${{ github.event_name == 'push' && 'prod' || (github.event.inputs.channel || 'prod') }}
135136
# Sign + notarize on macOS only when BOTH the signing cert and the Apple ID
136137
# notarization secrets are present; otherwise build unsigned instead of failing.
137138
DEEPAGENT_CODE_ALLOW_UNSIGNED: ${{ (matrix.group == 'mac' && env.HAS_APPLE_CERT == 'true' && env.HAS_APPLE_NOTARY == 'true') && '0' || '1' }}
@@ -155,5 +156,4 @@ jobs:
155156
path: |
156157
packages/desktop/dist/*.dmg
157158
packages/desktop/dist/*.deb
158-
packages/desktop/dist/*.rpm
159159
packages/desktop/dist/*.exe

.github/workflows/pr-routing.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: pr-routing
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, reopened, edited, synchronize, ready_for_review]
6+
7+
permissions:
8+
contents: read
9+
issues: write
10+
pull-requests: write
11+
12+
jobs:
13+
enforce-target:
14+
runs-on: ubuntu-24.04
15+
steps:
16+
- name: Enforce PR target branches
17+
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
18+
with:
19+
script: |
20+
const pr = context.payload.pull_request;
21+
const sameRepo = pr.head.repo.full_name === pr.base.repo.full_name;
22+
const contributorToDev = pr.base.ref === 'dev';
23+
const devToMain = pr.base.ref === 'main' && sameRepo && pr.head.ref === 'dev';
24+
25+
if (contributorToDev || devToMain) {
26+
core.info(`Allowed PR route: ${pr.head.repo.full_name}:${pr.head.ref} -> ${pr.base.ref}`);
27+
return;
28+
}
29+
30+
const marker = '<!-- pr-routing:invalid-target -->';
31+
const body = `${marker}
32+
This repository only accepts contributor PRs targeting \`dev\`.
33+
34+
The only allowed PR route into \`main\` is a same-repository \`dev\` -> \`main\` PR opened by a maintainer after \`dev\` has passed validation.
35+
36+
Please reopen this change against \`dev\`.`;
37+
38+
const { data: comments } = await github.rest.issues.listComments({
39+
owner: context.repo.owner,
40+
repo: context.repo.repo,
41+
issue_number: pr.number,
42+
per_page: 100,
43+
});
44+
45+
const existing = comments.find((comment) => comment.body?.includes(marker));
46+
if (!existing) {
47+
await github.rest.issues.createComment({
48+
owner: context.repo.owner,
49+
repo: context.repo.repo,
50+
issue_number: pr.number,
51+
body,
52+
});
53+
}
54+
55+
await github.rest.pulls.update({
56+
owner: context.repo.owner,
57+
repo: context.repo.repo,
58+
pull_number: pr.number,
59+
state: 'closed',
60+
});
61+
62+
core.setFailed(`Invalid PR route: ${pr.head.repo.full_name}:${pr.head.ref} -> ${pr.base.ref}`);

.github/workflows/pr-standards.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ jobs:
1717
script: |
1818
const pr = context.payload.pull_request;
1919
const login = pr.user.login;
20+
if (pr.base.ref !== 'dev') {
21+
console.log(`Skipping PR standards for base branch ${pr.base.ref}`);
22+
return;
23+
}
2024
2125
// Skip PRs older than Feb 18, 2026 at 6PM EST (Feb 19, 2026 00:00 UTC)
2226
const cutoff = new Date('2026-02-19T00:00:00Z');
@@ -164,6 +168,10 @@ jobs:
164168
script: |
165169
const pr = context.payload.pull_request;
166170
const login = pr.user.login;
171+
if (pr.base.ref !== 'dev') {
172+
console.log(`Skipping PR compliance for base branch ${pr.base.ref}`);
173+
return;
174+
}
167175
168176
// Skip PRs older than Feb 18, 2026 at 6PM EST (Feb 19, 2026 00:00 UTC)
169177
const cutoff = new Date('2026-02-19T00:00:00Z');

0 commit comments

Comments
 (0)