Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
3665837
chore: amend Roomote 1.8.0 release notes (#2549)
roomote-roomote[bot] Sep 11, 2026
e9b0d60
[Improve] Use consistent default destinations for automations (#2546)
roomote-roomote[bot] Sep 11, 2026
1eb90f4
[Docs] Clarify Docker environments and sidebar labels (#2550)
roomote-roomote[bot] Sep 11, 2026
4d8bc9f
[Feat] Merge pull requests directly in Fast (#2551)
roomote-roomote[bot] Sep 11, 2026
47e0251
[Fix] Telegram Fast messages show automatic eyes reactions (#2552)
roomote-roomote[bot] Sep 11, 2026
e33021b
[Fix] Integration discovery reports filter misses clearly (#2557)
roomote-roomote[bot] Sep 11, 2026
b9f7820
fix: include Telegram reply context (#2556)
roomote-roomote[bot] Sep 11, 2026
77bb84c
fix: sync Telegram Fast topic titles (#2553)
roomote-roomote[bot] Sep 11, 2026
2510e61
fix: accept null and filler optional args on Fast skill lookups (#2559)
mrubens Sep 11, 2026
1c4bd9e
[Improve] Show native Thinking during Telegram Fast turns (#2558)
roomote-roomote[bot] Sep 11, 2026
8977ffe
[Improve] Stream Fast replies natively in Telegram (#2560)
roomote-roomote[bot] Sep 11, 2026
a79f07e
fix(web): hide failed tool status labels (#2554)
roomote-roomote[bot] Sep 11, 2026
9a13356
[Feat] Show compact live coding progress in Telegram (#2555)
roomote-roomote[bot] Sep 11, 2026
a058f02
[Fix] Telegram voice messages fail to transcribe (#2561)
roomote-roomote[bot] Sep 11, 2026
9a7b499
[Fix] Telegram topic icons stay provisional when titles generate (#2562)
roomote-roomote[bot] Sep 11, 2026
d8d8ac5
fix: stream Telegram Fast drafts more frequently (#2564)
roomote-roomote[bot] Sep 11, 2026
7c9a42b
fix(web): normalize voice transcript whitespace (#2566)
roomote-roomote[bot] Sep 11, 2026
d5d93ec
fix: stream first Telegram Fast draft immediately (#2567)
roomote-roomote[bot] Sep 11, 2026
5277b4c
[Improve] Follow coding tasks every minute during voice calls (#2565)
roomote-roomote[bot] Sep 12, 2026
5bc974a
[Fix] Telegram Fast replies show a blank draft before streaming (#2571)
roomote-roomote[bot] Sep 12, 2026
6b4475a
[Fix] Automation reports post unthreaded in Telegram DMs (#2569)
roomote-roomote[bot] Sep 12, 2026
c2866cc
[Fix] PR review notifications omit action buttons on Telegram (#2573)
roomote-roomote[bot] Sep 12, 2026
869a339
fix: stabilize Telegram Fast topic titles (#2575)
roomote-roomote[bot] Sep 12, 2026
539f303
fix: ignore non-task Telegram DM updates (#2570)
roomote-roomote[bot] Sep 12, 2026
465e459
[Fix] Telegram topic icons repeat across different generated titles (…
roomote-roomote[bot] Sep 12, 2026
97ba4e5
[Improve] Arrange Telegram review actions across two rows (#2577)
roomote-roomote[bot] Sep 12, 2026
707e305
[Fix] Session transcripts show timer setup receipts (#2576)
roomote-roomote[bot] Sep 12, 2026
beab78a
[Fix] Telegram working status flickers on short Fast turns (#2578)
roomote-roomote[bot] Sep 12, 2026
dd64612
[Feat] Notify absent users when web tasks settle (#2580)
roomote-roomote[bot] Sep 12, 2026
accc3cf
chore(deps): update smol-toml to 1.7.1 (#2584)
roomote-roomote[bot] Sep 12, 2026
d46cf0f
[Improve] Link task memories in the Brain to the member who started t…
mrubens Sep 12, 2026
62d11a5
[Fix] Telegram replies lose content when responses exceed the message…
roomote-roomote[bot] Sep 12, 2026
1c06930
fix: retire Telegram review buttons persistently (#2587)
roomote-roomote[bot] Sep 12, 2026
667d789
[Fix] Telegram working status disappears during active Fast turns (#2…
roomote-roomote[bot] Sep 12, 2026
8e4fa43
[Fix] Telegram first messages lose attachments in new Sessions (#2586)
roomote-roomote[bot] Sep 12, 2026
4024232
[Fix] Fast widgets fail during BullMQ-resumed turns (#2593)
roomote-roomote[bot] Sep 12, 2026
aa3ac8f
feat: identify Telegram automation runs (#2590)
roomote-roomote[bot] Sep 12, 2026
f746a0b
[Fix] Telegram trusts unrelated mentions when bot identity is unavail…
roomote-roomote[bot] Sep 12, 2026
c2e8b14
[Improve] Share widget links across communication providers (#2599)
roomote-roomote[bot] Sep 12, 2026
eeb6920
docs: remove obsolete Memory configuration guidance (#2589)
roomote-roomote[bot] Sep 12, 2026
7462e0e
[Fix] Tasks load failures leave users without a retry (#2591)
roomote-roomote[bot] Sep 12, 2026
f09f750
[Fix] Session artifact helpers allow non-human metadata reads (#2594)
roomote-roomote[bot] Sep 12, 2026
3502f97
[Fix] Deployment accepts malformed domain names (#2595)
roomote-roomote[bot] Sep 12, 2026
e7f9939
[Fix] Hide managed Email configuration on Roomote Cloud (#2568)
roomote-roomote[bot] Sep 12, 2026
31509ee
[Feat] Send all Telegram text as rich messages (#2600)
roomote-roomote[bot] Sep 12, 2026
41b4aba
[Feat] Let agents update shared custom skills (#2602)
roomote-roomote[bot] Sep 12, 2026
153c5da
fix: clarify Experimental Results setting (#2603)
roomote-roomote[bot] Sep 12, 2026
6be58cb
[Fix] Telegram replies preserve paragraphs and lists (#2604)
roomote-roomote[bot] Sep 12, 2026
4ccae7b
feat: use details for Telegram task progress (#2605)
roomote-roomote[bot] Sep 12, 2026
06a6bdb
[Fix] Telegram topic icons better match generated titles (#2607)
roomote-roomote[bot] Sep 12, 2026
f8352ef
[Fix] Tasks launch in the wrong environment (#2606)
roomote-roomote[bot] Sep 12, 2026
7928cf2
[Feat] Render Telegram replies with native Rich Markdown (#2608)
roomote-roomote[bot] Sep 12, 2026
842f1d8
feat: add Telegram goal command (#2610)
roomote-roomote[bot] Sep 12, 2026
6ae8839
[Fix] Telegram elicitations leave stale buttons and broken formatting…
roomote-roomote[bot] Sep 13, 2026
810e3af
[Improve] Move mobile Session switching into a left rail (#2609)
roomote-roomote[bot] Sep 13, 2026
6f2db30
[Improve] Put mobile recent sessions in the navigation menu (#2613)
roomote-roomote[bot] Sep 13, 2026
16e2661
[Improve] Show Telegram automation titles as headings (#2616)
roomote-roomote[bot] Sep 13, 2026
7cc7a2f
fix: stop editing Telegram live task messages to Completed (#2597)
roomote-roomote[bot] Sep 13, 2026
a7ae606
[Improve] Remove Telegram reply quotes (#2617)
roomote-roomote[bot] Sep 13, 2026
83b0b77
chore: release Roomote 1.9.0 (#2624)
roomote-roomote[bot] Sep 13, 2026
6e334e6
fix: redirect signed-in users from login (#2626)
roomote-roomote[bot] Sep 13, 2026
946f2a0
fix: honor safe login return paths (#2627)
roomote-roomote[bot] Sep 13, 2026
537ea83
fix: show Results load errors with retry (#2620)
roomote-roomote[bot] Sep 13, 2026
79240e7
fix: retry sandbox provider status loading (#2621)
roomote-roomote[bot] Sep 13, 2026
e12d2e7
fix(web): name collapsed sidebar actions (#2623)
roomote-roomote[bot] Sep 13, 2026
431cfbc
[Fix] Local MinIO bootstrap in Roomote development/test sandboxes (#2…
roomote-roomote[bot] Sep 13, 2026
b39be5f
[Feat] Make web Session notifications timely and replyable (#2629)
roomote-roomote[bot] Sep 13, 2026
ce42898
[Improve] Make Goal Mode persist across Fast Sessions (#2630)
roomote-roomote[bot] Sep 13, 2026
341b6cc
[Fix] Web Session notifications hide responses and duplicate delivery…
roomote-roomote[bot] Sep 13, 2026
0b14a94
[Feat] Add owner-approved API keys to Fast Sessions (#2383)
roomote-roomote[bot] Sep 13, 2026
7bf5587
[Fix] Absent Session notifications show stale or inconsistent footers…
roomote-roomote[bot] Sep 13, 2026
0081164
[Improve] Focus Session API key approval on secure entry (#2639)
roomote-roomote[bot] Sep 13, 2026
5e77ae6
fix: keep title models from answering questions (#2641)
roomote-roomote[bot] Sep 13, 2026
801688e
[Feat] Suggest home tasks from recent memories (#2646)
roomote-roomote[bot] Sep 13, 2026
84f882d
feat(web): improve home composer suggestions (#2650)
roomote-roomote[bot] Sep 14, 2026
9dc71ea
fix(web): hide home placeholders while loading (#2651)
roomote-roomote[bot] Sep 14, 2026
5f26ca8
[Feat] Add experimental personalized Home suggestions (#2652)
roomote-roomote[bot] Sep 14, 2026
37a6ecc
[Improve] Mark web conversation gaps in Session notifications (#2647)
roomote-roomote[bot] Sep 14, 2026
efe285d
fix: authenticate Azure inference gateway requests (#2662)
roomote-roomote[bot] Sep 14, 2026
1fdbc28
fix(web): match artifact surfaces to app background (#2663)
roomote-roomote[bot] Sep 14, 2026
3a57303
[Improve] Refine Automation Results readability (#2664)
roomote-roomote[bot] Sep 14, 2026
cf512fc
[Fix] Automation result previews use inconsistent styling (#2665)
roomote-roomote[bot] Sep 14, 2026
905a05a
feat: accept automation reports when deliverable PR merges (#2667)
roomote-roomote[bot] Sep 14, 2026
7151bcf
fix(web): preserve composer focus after sends (#2669)
roomote-roomote[bot] Sep 14, 2026
acb29cf
[Fix] Home suggestions load slowly after cache warmup (#2668)
roomote-roomote[bot] Sep 14, 2026
cfd6a57
fix(web): stabilize optimistic user avatars (#2670)
roomote-roomote[bot] Sep 14, 2026
b14348d
[Fix] Automations fail for discoverable Slack channels (#2672)
roomote-roomote[bot] Sep 14, 2026
96e0f6e
[Improve] Precompute Home suggestions after memory ingestion (#2671)
roomote-roomote[bot] Sep 14, 2026
aeaf3a3
[Fix] Gemini agents fail when Session-secret tools are available (#2674)
roomote-roomote[bot] Sep 14, 2026
2e0b09b
[Chore] Record Roomote 1.8.1 on develop after production hotfix (#2675)
roomote-roomote[bot] Sep 14, 2026
c65dd48
[Fix] Integration field errors are not announced to assistive technol…
roomote-roomote[bot] Sep 14, 2026
258fa14
fix(web): show experimental preferences load errors (#2655)
roomote-roomote[bot] Sep 14, 2026
41f2237
fix(web): expose Session utility panel state (#2658)
roomote-roomote[bot] Sep 14, 2026
f74ea2c
fix(api): reject malformed controller heartbeats (#2659)
roomote-roomote[bot] Sep 14, 2026
32b4c25
fix(web): reject failed prompt attachment downloads (#2661)
roomote-roomote[bot] Sep 14, 2026
c4d7444
[Fix] Personalized Home suggestions fall back after generation (#2678)
roomote-roomote[bot] Sep 14, 2026
963cc9a
[Fix] Analytics stays stuck when initial load fails (#2656)
roomote-roomote[bot] Sep 14, 2026
c463f9d
[Fix] Slack channel history reads fail in busy channels (#2681)
mrubens Sep 14, 2026
6a96412
[Improve] Make setup conversational and agent-led (#2539)
roomote-roomote[bot] Sep 14, 2026
0575bf2
[Feat] Check out all-repositories workspaces on demand (#2680)
mrubens Sep 14, 2026
217f730
feat(web): center text artifact content (#2684)
roomote-roomote[bot] Sep 14, 2026
9f7180e
[Docs] Remove redundant ChatGPT subscription guide (#2687)
roomote-roomote[bot] Sep 14, 2026
78ffdc8
[Fix] Fast Session replies notify users while they are viewing (#2685)
roomote-roomote[bot] Sep 14, 2026
d33856f
[Docs] Document Live Previews (#2686)
roomote-roomote[bot] Sep 14, 2026
98e8d9d
[Chore] Record Roomote 1.8.2 on develop after production hotfix (#2683)
roomote-roomote[bot] Sep 14, 2026
6f571fe
fix(dev): await initial worker release build (#2660)
roomote-roomote[bot] Sep 14, 2026
3043992
fix(web): add retries to initial load errors (#2689)
roomote-roomote[bot] Sep 14, 2026
a2c974e
[Fix] Personalized Home suggestions fail with Luna helpers (#2691)
roomote-roomote[bot] Sep 14, 2026
610e1c0
[Feat] Add first-use consent for Cloud voice (#2693)
roomote-roomote[bot] Sep 14, 2026
9e55b99
[Fix] Closed agent panels reappear when users revisit sessions (#2692)
PierrunoYT Sep 14, 2026
98a663a
[Fix] Fast sessions reject undeclared integration tool arguments inst…
mrubens Sep 14, 2026
5bafa3c
[Improve] Fast Sessions see instance and environment skills in every …
mrubens Sep 14, 2026
fb5b834
[Improve] Bound chat channel history results and tell the agent how t…
mrubens Sep 14, 2026
51d876c
[Fix] Keep inference gateway SSE streams alive during silent provider…
mrubens Sep 14, 2026
c5ee153
[Fix] Setup capability offers ignore qualifiers that do not apply to …
mrubens Sep 14, 2026
d5ab83d
[Fix] Normal Sessions are blocked by onboarding first-work selection …
roomote-roomote[bot] Sep 14, 2026
b16fe44
[Fix] Blank slate workspaces configure git and check repositories out…
mrubens Sep 14, 2026
271c47c
[Fix] Session prompt loses focus when task panels expand (#2533)
roomote-roomote[bot] Sep 14, 2026
800fcef
[Fix] Retry OpenCode turns that go idle with a provider-interrupted t…
mrubens Sep 14, 2026
a08f956
[Fix] Pull MinIO images from quay.io after their removal from Docker …
mrubens Sep 14, 2026
f1eb200
[Fix] Goal-created Sessions show stale status and titles (#2703)
roomote-roomote[bot] Sep 14, 2026
5e73277
Amend Roomote 1.9.0 release candidate (#2694)
roomote-roomote[bot] Sep 14, 2026
45782b5
[Fix] Reconciliation accepts stale PR base snapshots (#2706)
roomote-roomote[bot] Sep 14, 2026
6f2d2d6
[Fix] Temporarily hide unavailable Session secret tools (#2690)
daniel-lxs Sep 14, 2026
f8ecd73
[Chore] Build and publish our own MinIO image from the pinned communi…
mrubens Sep 14, 2026
cc6e91c
Replace Roomote 1.9.0 release candidate (#2711)
roomote-roomote[bot] Sep 14, 2026
335959d
Reconcile v1.9.0 with pinned main
github-actions[bot] Sep 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 7 additions & 2 deletions .agents/skills/changeset-release-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,13 @@ Release refresh deliberately refuses that state; push-triggered Release runs
also refuse to replace its metadata with the original version-bump SHA. Do not
force the candidate back onto develop. Reconcile a later pinned production base
through another reviewed run, or obtain a separately audited replacement-release
decision if newer develop work is needed. If any pin, approval, publication, or
scope guard fails, stop and re-audit rather than bypassing it.
decision if newer develop work is needed. An explicitly authorized same-version
replacement uses the Release workflow with the full current candidate SHA and
audited develop SHA; its force-with-lease comparison is CI-owned, requires the
release bot, and invalidates all checks, reviews, and reconciliation provenance
from the prior candidate. Never reproduce that replacement with a manual push.
If any pin, approval, publication, or scope guard fails, stop and re-audit
rather than bypassing it.

## Emergency direct-to-main hotfix path

Expand Down
6 changes: 6 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ Chores, docs-only, and pure-internal refactors can skip a changeset; they ride a
Candidate** workflow with pinned candidate/main commits and an independently
approved resolution on an ordinary branch. Never push a release branch
manually. See the [release skill](../.agents/skills/changeset-release-pr/SKILL.md#reconcile-a-frozen-candidate-with-production).
If a reconciled candidate must instead be replaced from `develop` without
changing its unpublished version, dispatch Release with the exact current
candidate and audited `develop` SHAs. This explicit replacement uses a
force-with-lease comparison against the pinned candidate, requires the
release bot, and invalidates all prior candidate checks and reconciliation
provenance.
4. Merge the Promote PR with a **merge commit** (not squash) into `main` to tag
`vX.Y.Z`. GHCR builds the matching images, and the GitHub Release is created
only after those images exist so `releases/latest` never points at a missing
Expand Down
1 change: 1 addition & 0 deletions .docker/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,16 @@
ENV S3_ENDPOINT=http://minio:9000
ENV S3_PRESIGN_ENDPOINT=http://minio:9000
ENV S3_REGION=us-east-1
ENV S3_ACCESS_KEY_ID=roomote

Check warning on line 118 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "S3_ACCESS_KEY_ID") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV S3_SECRET_ACCESS_KEY=roomote-local-artifacts-password

Check warning on line 119 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "S3_SECRET_ACCESS_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV S3_BUCKET_ARTIFACTS=roomote-artifacts
ENV JOB_AUTH_PRIVATE_KEY=local-self-host-build-job-auth-private-key

Check warning on line 121 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "JOB_AUTH_PRIVATE_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV JOB_AUTH_PUBLIC_KEY=local-self-host-build-job-auth-public-key
ENV PREVIEW_AUTH_PRIVATE_KEY=local-self-host-build-preview-auth-private-key

Check warning on line 123 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "PREVIEW_AUTH_PRIVATE_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV PREVIEW_AUTH_PUBLIC_KEY=local-self-host-build-preview-auth-public-key
ENV DASHBOARD_PASSWORD=roomote-local-admin

Check warning on line 125 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "DASHBOARD_PASSWORD") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV ENCRYPTION_KEY=local-roomote-encryption-key-0001

Check warning on line 126 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "ENCRYPTION_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV ARTIFACT_SIGNING_KEY=local-roomote-artifact-signing-key-1

Check warning on line 127 in .docker/app/Dockerfile

View workflow job for this annotation

GitHub Actions / Docker Build (app, amd64)

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "ARTIFACT_SIGNING_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV PREVIEW_PROXY_BASE_URL=http://localhost:18081
ENV PREVIEW_DOMAINS=localhost,127.0.0.1,roomotepreview.localhost

Expand Down Expand Up @@ -433,6 +433,7 @@
COPY --from=github-cli /usr/bin/gh /usr/local/bin/gh
RUN command -v git >/dev/null && command -v gh >/dev/null && \
command -v opencode >/dev/null && \
test -f /roomote/apps/bullmq/dist/xhr-sync-worker.js && \
cd /roomote/apps/bullmq && node -e "require.resolve('zod/package.json')" && \
ls -d /roomote/node_modules/.pnpm/zod@*/node_modules/zod >/dev/null

Expand Down
123 changes: 123 additions & 0 deletions .docker/minio/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# syntax=docker/dockerfile:1
#
# MinIO (object storage) and mc (its client), built from the last community
# source releases and published as ghcr.io/roocodeinc/roomote-minio.
#
# MinIO Community Edition went source-only on 2025-10-23 and the upstream
# repositories are archived; the prebuilt images were removed from Docker Hub
# in September 2026 and only linger on quay.io. Building from the pinned,
# checksum-verified source is the only distribution nobody else can delete
# out from under a deployment. Hosted (Railway) and self-hosted (compose,
# Coolify, Render) deployments run this same image.
#
# The build is byte-for-byte the one apps/api/scripts/setup-sandbox-minio.ts
# performs for sandboxes: same Go toolchain, same module version and Go
# checksum-database sums, same flags, and the resulting binaries are asserted
# against the same SHA-256 values. deploy/ci/validate-deployment-artifacts.mjs
# keeps the two pin sets identical.
#
# Upgrading: bump the *_RELEASE / *_MODULE_VERSION / *_SUM args together with
# the sandbox script (there will be no newer upstream releases; a bump only
# happens if we ever fork), then let the publish-minio workflow produce the
# digest to pin in deploy/deployment-catalog.json.

ARG GO_IMAGE=golang:1.24.8-bookworm@sha256:4ed690d6649d63c312b99a6120025ec79ce3b542968a37da53d6236c7c61a848
ARG RUNTIME_IMAGE=debian:bookworm-slim@sha256:88200866dfff7ea7f5cbcb6ec7c8a701889efe6fe859fe64d6990e4b07ea4171

# Upstream release names, declared before the first stage so both stages (and
# the publish workflow, which reads MINIO_RELEASE from this file) share them.
ARG MINIO_RELEASE=RELEASE.2025-10-15T17-29-55Z
ARG MC_RELEASE=RELEASE.2025-08-13T08-35-41Z

FROM ${GO_IMAGE} AS build

ARG TARGETARCH

# MinIO server: github.com/minio/minio at its final community release.
ARG MINIO_RELEASE
ARG MINIO_MODULE_VERSION=v0.0.0-20251015172955-9e49d5e7a648
ARG MINIO_MODULE_SUM=h1:6TdolSCLSs2nwm8i0PpWDqf9iX2Ty9WQK8wmr7dCnUM=
ARG MINIO_GOMOD_SUM=h1:yCWDkwWO9IWpGsT4mreDDN/B/QVmK2zC666uInRAcqE=
ARG MINIO_SHA256_AMD64=6456634c06fa937dfeb708e37db80c8a02ffc50874d211ee3fc5cc0f71f95b96
ARG MINIO_SHA256_ARM64=3f9e2d92ca9fe43ebac8f069349a3fefb91500ed06b22697e9d9f3dba6e1db17

# MinIO client: github.com/minio/mc at its final community release. Bundled
# because deployments create the artifact bucket with it (compose minio-init)
# and Coolify's documented container healthcheck is `mc ready local`.
ARG MC_RELEASE
ARG MC_MODULE_VERSION=v0.0.0-20250813083541-7394ce0dd2a8
ARG MC_MODULE_SUM=h1:9tuRE4iEaDkuxatxe7pddYYh1SX5mT0/D0haofZFeTY=
ARG MC_GOMOD_SUM=h1:agCKg3UT5wU3auhPL2lZbOWlqqT2RokeAT7Xc+HK3cU=
ARG MC_SHA256_AMD64=38b9aa4ae9eb7eda22c4010199dc3f85099266f063efca793aed29b5a95612ae
ARG MC_SHA256_ARM64=d0c72d33cf6a30a1f0b69a327c6f5dea065fa5b3d0c5dc7cf87f8de102384a98

# Mirrors the sandbox script's Go environment: the public proxy and checksum
# database authenticate the module, and the pinned toolchain plus -trimpath
# make the build reproducible so the SHA-256 assertions hold on any builder.
ENV CGO_ENABLED=0 \
GOOS=linux \
GOENV=off \
GOFLAGS=-mod=readonly \
GONOSUMDB= \
GOPRIVATE= \
GOPROXY=https://proxy.golang.org \
GOSUMDB=sum.golang.org \
GOTOOLCHAIN=local

# Set to 0 only when computing new pins (see build.sh); published builds
# always verify.
ARG VERIFY_SHA256=1

COPY build.sh /usr/local/bin/build-minio-module

RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
build-minio-module minio github.com/minio/minio \
"$MINIO_RELEASE" "$MINIO_MODULE_VERSION" "$MINIO_MODULE_SUM" "$MINIO_GOMOD_SUM" \
"$MINIO_SHA256_AMD64" "$MINIO_SHA256_ARM64"

RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
build-minio-module mc github.com/minio/mc \
"$MC_RELEASE" "$MC_MODULE_VERSION" "$MC_MODULE_SUM" "$MC_GOMOD_SUM" \
"$MC_SHA256_AMD64" "$MC_SHA256_ARM64"


FROM ${RUNTIME_IMAGE}

ARG MINIO_RELEASE
ARG MC_RELEASE

# ca-certificates so MinIO can reach TLS endpoints (KMS, replication targets);
# curl for operators and healthchecks. A shell stays available on purpose:
# compose runs `sh -c` bucket bootstrap against this image.
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*

COPY --from=build /out/minio /out/mc /usr/local/bin/
COPY --from=build /licenses /licenses
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

# MC_CONFIG_DIR: mc must be usable by whatever user runs the container; its
# default config lives under $HOME, which need not be writable.
# MINIO_UPDATE=off: there will never be another upstream release to check for.
ENV MC_CONFIG_DIR=/tmp/.mc \
MINIO_UPDATE=off

# Runs as root like the upstream image so existing /data volumes provisioned
# under it keep their ownership. Drop privileges with MINIO_UID/MINIO_GID if a
# deployment needs to.

LABEL org.opencontainers.image.title="Roomote MinIO" \
org.opencontainers.image.description="MinIO server and mc client built from the final community source releases" \
org.opencontainers.image.source="https://github.com/RooCodeInc/Roomote" \
org.opencontainers.image.licenses="AGPL-3.0-only" \
org.opencontainers.image.version="${MINIO_RELEASE}" \
io.roomote.minio.release="${MINIO_RELEASE}" \
io.roomote.mc.release="${MC_RELEASE}"

EXPOSE 9000 9001

ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["minio"]
93 changes: 93 additions & 0 deletions .docker/minio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# roomote-minio

MinIO server and `mc` client, compiled from the final MinIO Community Edition
source releases and published as `ghcr.io/roocodeinc/roomote-minio`.

## Why this exists

MinIO stopped publishing binaries and container images for the community
edition in October 2025 and archived the source repositories. The Docker Hub
images were deleted in September 2026 and the quay.io copies have no stated
future. Roomote deployments of every shape (Railway, compose, Coolify, Render)
need an artifact store whose image nobody else can remove, so we build it
from the pinned source ourselves.

## What is pinned

Everything that could change the output is pinned in the `Dockerfile` and
verified during the build:

| Pin | Verified by |
| ------------------------------------- | ---------------------------------------------- |
| Go toolchain image (by digest) | Docker |
| Module version and `h1:` sums | Go checksum database, compared to the args |
| Compiled binary SHA-256 per arch | `sha256sum` after `go build`, compared to args |
| Runtime base image (by digest) | Docker |

The MinIO pins are the same values `apps/api/scripts/setup-sandbox-minio.ts`
uses to build MinIO for sandboxes, and `deploy/ci/validate-deployment-artifacts.mjs`
fails if the two drift. A sandbox and a deployment therefore run the identical
binary.

Both builds pass `-trimpath -ldflags="-buildid= -s -w"`: no VCS or path
noise, no toolchain-derived build ID, no DWARF or symbol table (upstream's
release builds stripped them too; the binaries are about a quarter smaller).

The checksums are for **native** builds, meaning the Go toolchain runs on the
same architecture it targets. That is how the CI runners build (one amd64,
one arm64 runner) and how the linux/amd64 sandbox builds. `mc` reproduces
from any host with these flags, but `minio`'s code differs by a few hundred
bytes when the compiler runs on the other host architecture (same symbol
table and sizes, different instruction bytes, so it is codegen rather than
metadata). A cross-compile from an Apple Silicon laptop therefore matches the
arm64 pins but not the amd64 pins; use `docker build --platform linux/amd64`,
which runs the real linux/amd64 toolchain under emulation, to verify those.

## Bumping a pin

There will be no newer upstream releases, so this only applies if the module
or toolchain pin ever changes (a fork, a Go security release).

1. Update the `*_RELEASE`, `*_MODULE_VERSION`, `*_MODULE_SUM`, `*_GOMOD_SUM`
or `GO_IMAGE` args. `go mod download -json <module>@<release>` prints the
version and sums.
2. Build once in report mode to learn the new binary checksums, for each arch:
`docker build --build-arg VERIFY_SHA256=0 --platform linux/arm64 .docker/minio`
and the same with `linux/amd64`. The build log prints `sha256=` per binary.
Both must be Docker builds for the stated platform (native or emulated), not
host cross-compiles, for the reason above.
3. Put the printed values in the `*_SHA256_*` args and in
`apps/api/scripts/setup-sandbox-minio.ts`, then build again without the
flag; the validator checks the two files agree.

## Publishing

`.github/workflows/publish-minio.yml` builds both architectures natively,
merges them into one manifest, and prints the `image@sha256:` pin in the job
summary. It runs on pushes to `develop` and `main` that touch this directory
and on manual dispatch. Deployments do not track a tag: copy the printed pin
into `deploy/deployment-catalog.json` and the compose and template files the
validator checks against it.

## Compatibility with the upstream image

- Same invocation: `server /data --console-address :9001` works unchanged;
the entrypoint prepends `minio` for `server` and flag arguments only.
- `mc` is on the path with `MC_CONFIG_DIR=/tmp/.mc`, so `mc ready local`
healthchecks and the compose `minio-init` bucket bootstrap work against
this one image. There is no separate client image.
- Runs as root like upstream so existing `/data` volumes keep working.
- `MINIO_UPDATE=off`: there are no further upstream releases to check for.
- Adds `curl` and a shell, which the upstream image lacked.

## Local build and smoke test

```bash
docker build -t roomote-minio:local .docker/minio
docker run --rm -d --name minio-smoke -p 19100:9000 \
-e MINIO_ROOT_USER=roomote -e MINIO_ROOT_PASSWORD=roomote-local-artifacts-password \
roomote-minio:local server /data
curl -fsS http://127.0.0.1:19100/minio/health/live
docker exec minio-smoke mc ready local
docker stop minio-smoke
```
71 changes: 71 additions & 0 deletions .docker/minio/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/bin/sh
# Build one MinIO Go module from the public proxy with every pin verified.
#
# Usage: build-minio-module <name> <module> <release> <module-version>
# <module-sum> <go.mod-sum> <sha256-amd64> <sha256-arm64>
#
# `go mod download` fetches the tagged release through the checksum database;
# the returned version and h1: sums must equal the pinned ones before anything
# is compiled, and the compiled binary must match the pinned SHA-256 for the
# target architecture. Any mismatch fails the build.
#
# `-ldflags="-buildid= -s -w"` drops the toolchain-derived build ID and the
# debug info, as upstream's release builds did. That makes mc reproducible from
# any host, but MinIO's compiled code still differs when the Go compiler runs
# on a different host architecture than it targets, so the pinned checksums
# are for NATIVE builds: the per-arch CI runners, or a Docker build for the
# stated --platform (emulated is fine, a host cross-compile is not).
#
# VERIFY_SHA256=0 (build arg) reports the checksums instead of enforcing them;
# use it once when bumping pins, never in a published build.
set -eu

name="$1"
module="$2"
release="$3"
expected_version="$4"
expected_sum="$5"
expected_gomod_sum="$6"
sha256_amd64="$7"
sha256_arm64="$8"

case "${TARGETARCH:?TARGETARCH is required}" in
amd64) expected_sha256="$sha256_amd64" ;;
arm64) expected_sha256="$sha256_arm64" ;;
*)
echo "Unsupported TARGETARCH: $TARGETARCH" >&2
exit 1
;;
esac
export GOARCH="$TARGETARCH"

json="$(go mod download -json "${module}@${release}")"
field() {
printf '%s\n' "$json" | sed -n "s/^[[:space:]]*\"$1\": \"\\(.*\\)\",\\{0,1\\}\$/\\1/p" | head -n 1
}
actual_version="$(field Version)"
actual_sum="$(field Sum)"
actual_gomod_sum="$(field GoModSum)"
source_dir="$(field Dir)"

check() {
if [ "$2" != "$3" ]; then
echo "$name: $1 mismatch: expected $3, got $2" >&2
exit 1
fi
}
check "module version" "$actual_version" "$expected_version"
check "module checksum" "$actual_sum" "$expected_sum"
check "go.mod checksum" "$actual_gomod_sum" "$expected_gomod_sum"
[ -d "$source_dir" ] || { echo "$name: module directory missing: $source_dir" >&2; exit 1; }

mkdir -p /out /licenses
cd "$source_dir"
go build -trimpath -ldflags="-buildid= -s -w" -o "/out/$name" .
cp LICENSE "/licenses/$name.LICENSE"

actual_sha256="$(sha256sum "/out/$name" | cut -d' ' -f1)"
if [ "${VERIFY_SHA256:-1}" = 1 ]; then
check "binary sha256 ($TARGETARCH)" "$actual_sha256" "$expected_sha256"
fi
echo "$name $release ($TARGETARCH) sha256=$actual_sha256"
13 changes: 13 additions & 0 deletions .docker/minio/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
# Mirrors the upstream image's contract: a bare server invocation such as
# `server /data --console-address :9001` (how every Roomote deployment shape
# runs it) gets the `minio` binary prepended; anything else (`mc ...`, `sh`)
# runs as given so the same image doubles as the client.
set -eu

case "${1:-}" in
'') set -- minio ;;
server | -*) set -- minio "$@" ;;
esac

exec "$@"
Loading
Loading