Skip to content

Commit 336ec07

Browse files
authored
v0.8.15: ci improvements, trigger machine resizing, connectors fixes
2 parents d59b02c + a96ea5c commit 336ec07

27 files changed

Lines changed: 687 additions & 249 deletions

File tree

.github/actions/docker-build/action.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ inputs:
1919
tags:
2020
description: Comma-separated list of tags to push.
2121
required: true
22+
max-cache-size-mb:
23+
description: >-
24+
Layer cache to retain after the post-job prune, in MB. Must stay above one
25+
build's working set (base + dependency layers + RUN --mount=type=cache
26+
dirs) or every build evicts what the next one needs. Falls back to the
27+
small-image default below when empty.
28+
required: false
2229

2330
# Registry logins must precede this action. provenance/sbom stay off: attestation
2431
# manifests break `imagetools create` retagging in promote-images.
@@ -42,11 +49,24 @@ runs:
4249
PLATFORMS: ${{ inputs.platforms }}
4350
run: echo "value=${GITHUB_REPOSITORY##*/}/${FILE#./}/${PLATFORMS//\//-}" >> "$GITHUB_OUTPUT"
4451

52+
# max-cache-size-mb is what bounds the disk: BuildKit's default GC is
53+
# time-based only (layers unused for 8 days), and setup-docker-builder skips
54+
# pruning altogether when the value is empty. On a repo that builds this
55+
# often nothing ever ages out, so the disks grew without limit —
56+
# app.Dockerfile/linux-amd64 reached 351 GB inside a day, and realtime, whose
57+
# image is under 300 MB, sat at 249 GB. Sticky disks bill at ~$0.51/GB-month,
58+
# so that was real money for layers no build would ever read again.
59+
#
60+
# The fallback is here rather than an input `default:` because callers pass
61+
# this from a matrix field, and an unset matrix key arrives as the empty
62+
# string — which counts as "provided", so a `default:` would never apply and
63+
# a row that forgot the field would silently go back to unbounded growth.
4564
- name: Set up Blacksmith builder
4665
if: inputs.provider == '' || inputs.provider == 'blacksmith'
4766
uses: useblacksmith/setup-docker-builder@a5256a73e30f09e37e3eceb8ca36043d17621d24 # v2
4867
with:
4968
cache-key: ${{ steps.cache-key.outputs.value }}
69+
max-cache-size-mb: ${{ inputs.max-cache-size-mb || '25600' }}
5070

5171
- name: Build and push (Blacksmith)
5272
if: inputs.provider == '' || inputs.provider == 'blacksmith'

.github/codeql/codeql-config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,11 @@ paths-ignore:
3131
- '**/dist/**'
3232
- '**/.next/**'
3333
- 'apps/docs/content/**'
34+
35+
# Do NOT add `queries:`, `packs:`, `query-filters:`, or `disable-default-queries`
36+
# here to try to speed the scan up. Under the code-scanning feature flag the
37+
# action's checkOverlayAnalysisFeatureEnabled treats any of those as
38+
# OverlayDisabledReason.NonDefaultQueries and permanently turns off overlay
39+
# (incremental) analysis. Extraction is ~53% of a run and is exactly what overlay
40+
# skips, so scoping the queries trades a documented up-to-10x win for a few
41+
# percent off the 27% query phase.

.github/workflows/ci.yml

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ jobs:
7676
# (/api/desktop/update) starts offering automatically.
7777
detect-desktop-changes:
7878
name: Detect Desktop Changes
79-
runs-on: blacksmith-4vcpu-ubuntu-2404
79+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }}
8080
timeout-minutes: 5
8181
if: github.event_name == 'push' && (github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/staging')
8282
outputs:
@@ -165,7 +165,15 @@ jobs:
165165
# build` ~260s). The same `next build` runs on 16 vCPU in the separate
166166
# Build App verification job, which does not gate anything; this one
167167
# was doing comparable work on half the cores.
168+
#
169+
# cache_mb is the layer cache the post-job prune retains, and it is the
170+
# only reason the sticky disks stay bounded — see docker-build's
171+
# action.yml. Rows that omit it take the small-image default there. The
172+
# app image overrides because it carries ~34 layers plus apt and bun
173+
# cache mounts for the whole monorepo; 100 GB is several builds' worth
174+
# of headroom over that working set.
168175
- dockerfile: ./docker/app.Dockerfile
176+
cache_mb: '102400'
169177
ecr_repo_secret: ECR_APP
170178
gh_runner: linux-x64-8-core
171179
bs_runner: blacksmith-16vcpu-ubuntu-2404
@@ -176,11 +184,11 @@ jobs:
176184
- dockerfile: ./docker/realtime.Dockerfile
177185
ecr_repo_secret: ECR_REALTIME
178186
gh_runner: ubuntu-latest
179-
bs_runner: blacksmith-4vcpu-ubuntu-2404
187+
bs_runner: blacksmith-2vcpu-ubuntu-2404
180188
- dockerfile: ./docker/pii.Dockerfile
181189
ecr_repo_secret: ECR_PII
182190
gh_runner: ubuntu-latest
183-
bs_runner: blacksmith-4vcpu-ubuntu-2404
191+
bs_runner: blacksmith-2vcpu-ubuntu-2404
184192
steps:
185193
- name: Checkout code
186194
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
@@ -214,6 +222,7 @@ jobs:
214222
file: ${{ matrix.dockerfile }}
215223
platforms: linux/amd64
216224
tags: ${{ steps.login-ecr.outputs.registry }}/${{ steps.ecr-repo.outputs.name }}:dev
225+
max-cache-size-mb: ${{ matrix.cache_mb }}
217226

218227
# Dev: deploy Trigger.dev background tasks to the preview "dev-sim" branch.
219228
# Gated after migrate-dev for the same reason as build-dev — the new task
@@ -280,6 +289,7 @@ jobs:
280289
matrix:
281290
include:
282291
- dockerfile: ./docker/app.Dockerfile
292+
cache_mb: '102400'
283293
ghcr_image: ghcr.io/simstudioai/simstudio
284294
ecr_repo_secret: ECR_APP
285295
gh_runner: linux-x64-8-core
@@ -293,12 +303,12 @@ jobs:
293303
ghcr_image: ghcr.io/simstudioai/realtime
294304
ecr_repo_secret: ECR_REALTIME
295305
gh_runner: ubuntu-latest
296-
bs_runner: blacksmith-4vcpu-ubuntu-2404
306+
bs_runner: blacksmith-2vcpu-ubuntu-2404
297307
- dockerfile: ./docker/pii.Dockerfile
298308
ghcr_image: ghcr.io/simstudioai/pii
299309
ecr_repo_secret: ECR_PII
300310
gh_runner: ubuntu-latest
301-
bs_runner: blacksmith-4vcpu-ubuntu-2404
311+
bs_runner: blacksmith-2vcpu-ubuntu-2404
302312
# No ECR repo is provisioned for cron, so it publishes to GHCR only.
303313
# The tag step below omits the ECR tag when the repo name is empty.
304314
- dockerfile: ./docker/cron.Dockerfile
@@ -382,6 +392,7 @@ jobs:
382392
file: ${{ matrix.dockerfile }}
383393
platforms: linux/amd64
384394
tags: ${{ steps.meta.outputs.tags }}
395+
max-cache-size-mb: ${{ matrix.cache_mb }}
385396

386397
# Promote the sha-tagged ECR images to the deploy tags once tests and
387398
# migrations pass. Pushing the ECR latest/staging tag is what triggers
@@ -484,6 +495,7 @@ jobs:
484495
# hang a release in `queued` rather than fail a PR.
485496
include:
486497
- dockerfile: ./docker/app.Dockerfile
498+
cache_mb: '102400'
487499
image: ghcr.io/simstudioai/simstudio
488500
gh_runner: linux-arm64-8-core
489501
bs_runner: blacksmith-8vcpu-ubuntu-2404-arm
@@ -522,6 +534,7 @@ jobs:
522534
file: ${{ matrix.dockerfile }}
523535
platforms: linux/arm64
524536
tags: ${{ matrix.image }}:${{ github.sha }}-arm64
537+
max-cache-size-mb: ${{ matrix.cache_mb }}
525538

526539
# Publish all mutable GHCR tags (latest, latest-amd64/arm64, version tags)
527540
# and the multi-arch manifests from the immutable sha tags — only on main,
@@ -675,7 +688,7 @@ jobs:
675688
# Job-level `if:` cannot read the secrets context, hence the probe job.
676689
check-desktop-signing:
677690
name: Check Desktop Signing Secrets
678-
runs-on: blacksmith-4vcpu-ubuntu-2404
691+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }}
679692
timeout-minutes: 2
680693
needs: [detect-version, detect-desktop-changes]
681694
# !cancelled(): detect-desktop-changes is skipped on main (and
@@ -724,7 +737,7 @@ jobs:
724737
# remains testable end to end with a manual download.
725738
create-desktop-prerelease:
726739
name: Create Desktop Prerelease
727-
runs-on: blacksmith-4vcpu-ubuntu-2404
740+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }}
728741
timeout-minutes: 5
729742
needs: [detect-desktop-changes, check-desktop-signing]
730743
# Requires the signing probe to have actually succeeded (not just "not
@@ -813,7 +826,7 @@ jobs:
813826
# point of view.
814827
publish-desktop-prerelease:
815828
name: Publish Desktop Prerelease
816-
runs-on: blacksmith-4vcpu-ubuntu-2404
829+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }}
817830
timeout-minutes: 5
818831
needs: [create-desktop-prerelease, desktop-prerelease]
819832
permissions:
@@ -837,7 +850,7 @@ jobs:
837850
# are always garbage by this point — the current run's release is published.
838851
prune-desktop-prereleases:
839852
name: Prune Desktop Prereleases
840-
runs-on: blacksmith-4vcpu-ubuntu-2404
853+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-2vcpu-ubuntu-2404' || 'ubuntu-latest' }}
841854
timeout-minutes: 5
842855
needs: [publish-desktop-prerelease]
843856
permissions:

.github/workflows/codeql.yml

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,16 @@ on:
2020
# created, prevents developers from introducing new vulnerabilities."
2121
push:
2222
branches: [main]
23+
# main only, not staging. Feature PRs land on staging and are ~90% of PR scan
24+
# volume, and every one of them is scanned again — against the exact tree being
25+
# promoted — when the staging->main PR opens. Scanning at the promotion
26+
# boundary defers the signal rather than dropping it.
27+
#
28+
# Deliberately a branch cut and not an activity-type cut: dropping
29+
# `synchronize` would have scanned each PR's first commit and never its final
30+
# state, which is backwards, since review fixups land in later pushes.
2331
pull_request:
24-
branches: [main, staging]
32+
branches: [main]
2533
# `ready_for_review` is not a default activity type, so it has to be listed
2634
# alongside the defaults it replaces. Without it, a PR opened as a draft and
2735
# then marked ready is skipped by the job-level draft guard and never
@@ -41,7 +49,15 @@ on:
4149
# Safety net behind the push trigger, and the thing that keeps the
4250
# default-branch alert view fresh when main is quiet. Only fires once this
4351
# file is on the default branch — schedule events ignore other branches.
44-
- cron: '17 8 * * 1'
52+
#
53+
# Daily rather than weekly. Pushes to main are rare, and with PR scans now
54+
# limited to main the alert view leans on this more than it used to; a week
55+
# is too long to leave it stale. It also reseeds the overlay-base database
56+
# that PR runs restore from — that cache key embeds the CodeQL bundle
57+
# version, so a bundle bump invalidates it, and an unused Actions cache is
58+
# evicted after 7 days. One 8 vCPU default-branch scan a day is a few
59+
# dollars a month against a PR scan that halves when the base is warm.
60+
- cron: '17 8 * * *'
4561
workflow_dispatch:
4662

4763
concurrency:
@@ -54,7 +70,12 @@ permissions:
5470
jobs:
5571
analyze:
5672
name: Analyze ${{ matrix.language }}
57-
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-8vcpu-ubuntu-2404' || 'ubuntu-latest' }}
73+
# Sized per language, not per workflow. The two analyses are nothing alike:
74+
# javascript-typescript peaks at 19.5 GB (p95 over 3090 runs), so it needs
75+
# the 8 vCPU tier's 30.4 GB and would OOM on the 4 vCPU tier's 15.2 GB; the
76+
# actions analysis peaks at 1.3 GB and averages 22% CPU over a 39s median
77+
# run, so 8 vCPU was 4x more machine than it ever used.
78+
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && matrix.bs_runner || 'ubuntu-latest' }}
5879
timeout-minutes: 60
5980
if: github.event.pull_request.draft != true
6081
permissions:
@@ -71,7 +92,11 @@ jobs:
7192
# entries default setup listed were one analysis, not three.
7293
# `javascript-typescript` is the documented spelling. Python dropped:
7394
# 7 files in the tree.
74-
language: [javascript-typescript, actions]
95+
include:
96+
- language: javascript-typescript
97+
bs_runner: blacksmith-8vcpu-ubuntu-2404
98+
- language: actions
99+
bs_runner: blacksmith-4vcpu-ubuntu-2404
75100

76101
steps:
77102
- name: Checkout repository

apps/sim/background/knowledge-connector-sync.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,14 @@ export async function executeConnectorSyncJob(payload: unknown) {
9898
export const knowledgeConnectorSync = task({
9999
id: 'knowledge-connector-sync',
100100
maxDuration: CONNECTOR_SYNC_MAX_DURATION_SECONDS,
101-
machine: 'large-2x',
101+
/**
102+
* Sized from production telemetry: peak sampled RSS 2.6 GB and peak 1.4 vCPU,
103+
* so `large-1x` holds ~3x memory and ~2.8x CPU headroom. No `outOfMemory`
104+
* escalation: an OOM is a SIGKILL, so the run never reaches the terminal
105+
* write that clears `syncLockToken`, and the escalated attempt would find the
106+
* row still `syncing` and skip. The stale-lock reaper owns that recovery.
107+
*/
108+
machine: 'large-1x',
102109
retry: {
103110
maxAttempts: 3,
104111
factor: 2,

apps/sim/background/knowledge-processing.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,13 @@ export async function runDocumentProcessing(
135135
export const processDocument = task({
136136
id: 'knowledge-process-document',
137137
maxDuration: envNumber(env.KB_CONFIG_MAX_DURATION, 600),
138-
machine: 'large-1x', // 4 vCPU, 8GB RAM - needed for large PDF processing
138+
/**
139+
* Sized from production telemetry: peak sampled RSS 902 MB and peak 1.2 vCPU
140+
* across a corpus where no document exceeded 2 GB, so `medium-2x` holds ~4x
141+
* memory and ~1.7x CPU headroom over the observed worst case. The prior
142+
* `large-1x` reserved 8 GB against a worst case using an eighth of it.
143+
*/
144+
machine: 'medium-2x',
139145
retry: {
140146
maxAttempts: envNumber(env.KB_CONFIG_MAX_ATTEMPTS, 3),
141147
factor: envNumber(env.KB_CONFIG_RETRY_FACTOR, 2),

apps/sim/lib/api/contracts/knowledge/documents.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,16 +319,23 @@ export const listKnowledgeDocumentsContract = defineRouteContract({
319319
},
320320
})
321321

322-
export const createKnowledgeDocumentsContract = defineRouteContract({
323-
method: 'POST',
324-
path: '/api/knowledge/[id]/documents',
322+
/**
323+
* Document creation from inline content has no HTTP route: `POST
324+
* /api/knowledge/[id]/documents` was retired when tool operations moved
325+
* in-process, and the surviving `GET`/`PATCH` on that path would answer a `POST`
326+
* with 405. So these stay plain schemas rather than a `defineRouteContract` —
327+
* `lib/internal/knowledge/execute-tool.ts` validates `knowledge_create_document`
328+
* against them directly. Callers wanting an HTTP upload use v1 or v2, both of
329+
* which take multipart file bodies rather than inline content.
330+
*/
331+
export const createKnowledgeDocumentsSchemas = {
325332
params: knowledgeBaseParamsSchema,
326333
body: createKnowledgeDocumentsBodySchema,
327-
response: {
328-
mode: 'json',
329-
schema: successResponseSchema(z.union([bulkCreateDocumentsResponseSchema, documentDataSchema])),
330-
},
331-
})
334+
} as const
335+
336+
export const createKnowledgeDocumentsResponseSchema = successResponseSchema(
337+
z.union([bulkCreateDocumentsResponseSchema, documentDataSchema])
338+
)
332339

333340
export const updateKnowledgeDocumentContract = defineRouteContract({
334341
method: 'PUT',

apps/sim/lib/api/contracts/selectors/confluence.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -399,14 +399,16 @@ export const confluencePageSelectorContract = definePostSelector(
399399
z.object({ id: z.string(), title: z.string() }).passthrough()
400400
)
401401

402-
export const confluenceUpdatePageContract = defineConfluencePutContract(
403-
'/api/tools/confluence/page',
404-
confluenceUpdatePageBodySchema
405-
)
406-
export const confluenceDeletePageContract = defineConfluenceDeleteContract(
407-
'/api/tools/confluence/page',
408-
confluenceDeletePageBodySchema
409-
)
402+
/**
403+
* Page update and delete have no contract because they have no route: the
404+
* `PUT`/`DELETE` handlers on `/api/tools/confluence/page` were retired when the
405+
* tool moved in process, and the surviving selector `POST` on that path would
406+
* answer either verb with 405. `lib/internal/confluence/execute-tool.ts`
407+
* validates both against `confluenceUpdatePageBodySchema` /
408+
* `confluenceDeletePageBodySchema` directly.
409+
*/
410+
export type ConfluenceUpdatePageBody = z.output<typeof confluenceUpdatePageBodySchema>
411+
export type ConfluenceDeletePageBody = z.output<typeof confluenceDeletePageBodySchema>
410412
export const confluenceDeleteAttachmentContract = defineConfluenceDeleteContract(
411413
'/api/tools/confluence/attachment',
412414
confluenceDeleteAttachmentBodySchema
@@ -562,8 +564,6 @@ export const confluenceUserContract = defineConfluencePostContract(
562564

563565
export type ConfluencePagesBody = ContractBody<typeof confluencePagesSelectorContract>
564566
export type ConfluencePageBody = ContractBody<typeof confluencePageSelectorContract>
565-
export type ConfluenceUpdatePageBody = ContractBody<typeof confluenceUpdatePageContract>
566-
export type ConfluenceDeletePageBody = ContractBody<typeof confluenceDeletePageContract>
567567
export type ConfluenceDeleteAttachmentBody = ContractBody<typeof confluenceDeleteAttachmentContract>
568568
export type ConfluenceListAttachmentsQuery = ContractQuery<typeof confluenceListAttachmentsContract>
569569
export type ConfluenceListBlogPostsQuery = ContractQuery<typeof confluenceListBlogPostsContract>

apps/sim/lib/api/contracts/tools/docusign.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

apps/sim/lib/api/contracts/tools/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export * from './communication'
44
export * from './crowdstrike'
55
export * from './custom'
66
export * from './databases'
7-
export * from './docusign'
87
export * from './file'
98
export * from './google'
109
export * from './imap'

0 commit comments

Comments
 (0)