snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 2s
This commit is contained in:
8
.changeset/README.md
Normal file
8
.changeset/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Changesets
|
||||
|
||||
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
|
||||
with multi-package repos, or single-package repos to help you version and publish your code. You can
|
||||
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
|
||||
|
||||
We have a quick list of common questions to get you started engaging with this project in
|
||||
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
|
||||
7
.changeset/all-lights-go.md
Normal file
7
.changeset/all-lights-go.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@rocket.chat/media-signaling': minor
|
||||
'@rocket.chat/media-calls': minor
|
||||
'@rocket.chat/ui-voip': minor
|
||||
---
|
||||
|
||||
Improves the logic of when the Busy Tone should be played after a call ends
|
||||
5
.changeset/argon2-musl-prebuild.md
Normal file
5
.changeset/argon2-musl-prebuild.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes the Docker image crashing at boot on arm64 with `Error loading shared library ld-linux-aarch64.so.1` while loading `argon2.node`. The Meteor bundle carries `build/Release` output compiled on the glibc-based CI host, and `node-gyp-build` prefers it over the musl binaries shipped under `prebuilds/` in the same package, so the wrong one was selected at runtime.
|
||||
5
.changeset/autotranslate-provider-switch.md
Normal file
5
.changeset/autotranslate-provider-switch.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes auto-translate continuing to translate messages with the previously selected service provider after switching providers, until the server was restarted or the feature was disabled and re-enabled.
|
||||
14
.changeset/config.json
Normal file
14
.changeset/config.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
|
||||
"changelog": ["@rocket.chat/release-changelog", { "repo": "RocketChat/Rocket.Chat" }],
|
||||
"commit": false,
|
||||
"fixed": [["@rocket.chat/meteor", "@rocket.chat/core-typings", "@rocket.chat/rest-typings"]],
|
||||
"linked": [],
|
||||
"access": "public",
|
||||
"baseBranch": "develop",
|
||||
"updateInternalDependencies": "patch",
|
||||
"ignore": [],
|
||||
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
|
||||
"onlyUpdatePeerDependentsWhenOutOfRange": true
|
||||
}
|
||||
}
|
||||
5
.changeset/css-supports-monorepo-migration.md
Normal file
5
.changeset/css-supports-monorepo-migration.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/css-supports': patch
|
||||
---
|
||||
|
||||
Moved `@rocket.chat/css-supports` into the Rocket.Chat monorepo, continuing from the frozen Fuselage 0.31.25 release. The memoized, SSR-safe `CSS.supports` facade keeps the same API and runtime behaviour; only its build, lint and test wiring changed, none of which is published.
|
||||
5
.changeset/curly-ravens-shout.md
Normal file
5
.changeset/curly-ravens-shout.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes the custom emoji picker returning zero emoji on workspaces running with `ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS=true`, caused by the client sending an empty `query` string to `emoji-custom.list`
|
||||
5
.changeset/ddp-deprecate-get-room-join-code.md
Normal file
5
.changeset/ddp-deprecate-get-room-join-code.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Deprecates the `getRoomJoinCode` real-time API method. It has had no caller since the room settings panel stopped revealing join codes, and will be removed in 9.0.0 without a replacement.
|
||||
5
.changeset/ddp-deprecate-raix-push-setuser.md
Normal file
5
.changeset/ddp-deprecate-raix-push-setuser.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Deprecates the `raix:push-setuser` real-time API method. It was inherited from the `raix:push` package for Cordova clients and has never been called by Rocket.Chat clients, which bind push tokens to users through `POST /v1/push.token`. It will be removed in 9.0.0 without a replacement.
|
||||
5
.changeset/ddp-migrate-get-messages-caller.md
Normal file
5
.changeset/ddp-migrate-get-messages-caller.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Deprecates the `getMessages` real-time API method in favor of the new `POST /v1/chat.getMessages` endpoint. The method keeps working until it is removed in 9.0.0.
|
||||
5
.changeset/ddp-migrate-room-history-callers.md
Normal file
5
.changeset/ddp-migrate-room-history-callers.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Deprecates the `loadHistory` and `loadNextMessages` real-time API methods in favor of the new `GET /v1/rooms.history` endpoint. Both methods keep working until they are removed in 9.0.0.
|
||||
6
.changeset/ddp-migrate-setup-wizard-callers.md
Normal file
6
.changeset/ddp-migrate-setup-wizard-callers.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
'@rocket.chat/ui-client': patch
|
||||
---
|
||||
|
||||
Migrates the setup wizard off the `getSetupWizardParameters`, `cloud:getWorkspaceRegisterData` and `registerUser` real-time API methods, in favor of `GET /v1/setupWizard.parameters`, `GET /v1/cloud.workspaceRegisterData` and `POST /v1/users.register`. The first two methods are now deprecated and keep working until they are removed in 9.0.0.
|
||||
5
.changeset/ddp-migrate-surrounding-messages-caller.md
Normal file
5
.changeset/ddp-migrate-surrounding-messages-caller.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Deprecates the `loadSurroundingMessages` real-time API method in favor of the `aroundId` parameter of `GET /v1/rooms.history`. The method keeps working until it is removed in 9.0.0.
|
||||
5
.changeset/deprecate-gravatar-integration.md
Normal file
5
.changeset/deprecate-gravatar-integration.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Deprecates the Gravatar integration. Default avatars fetched from Gravatar on user creation and Gravatar-based avatar suggestions in the profile settings will be removed in a future major release; a warning is now logged when they are used.
|
||||
7
.changeset/directory-leftover-federation-origin.md
Normal file
7
.changeset/directory-leftover-federation-origin.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@rocket.chat/model-typings': patch
|
||||
'@rocket.chat/models': patch
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes the admin and search directory omitting local users whose documents still carried data from the removed legacy federation, making them unsearchable in Directory > Users while still visible in Spotlight and Administration > Users.
|
||||
12
.changeset/fuzzy-terms-brake.md
Normal file
12
.changeset/fuzzy-terms-brake.md
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
'@rocket.chat/media-calls': minor
|
||||
'@rocket.chat/model-typings': minor
|
||||
'@rocket.chat/ui-voip': minor
|
||||
'@rocket.chat/models': minor
|
||||
'@rocket.chat/i18n': minor
|
||||
'@rocket.chat/core-typings': minor
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Adds name and avatar resolution for external voice calls
|
||||
5
.changeset/giphy-collapse-state-scroll.md
Normal file
5
.changeset/giphy-collapse-state-scroll.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes an issue where message attachments lose their collapsed state when scrolled out of view.
|
||||
15
.changeset/heavy-lions-attend.md
Normal file
15
.changeset/heavy-lions-attend.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
'@rocket.chat/federation-matrix': patch
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes federation endpoints rejecting requests that are valid per the Matrix specification:
|
||||
|
||||
- `publicRooms` (GET and POST) required params/fields the spec marks optional
|
||||
- `query/profile` rejected spec-valid profile fields such as `m.tz`
|
||||
- `get_missing_events` required the optional `limit` field and bounded it
|
||||
- `make_join` returned 500 instead of 400 `M_INCOMPATIBLE_ROOM_VERSION` for unsupported room versions
|
||||
- `backfill` rejected spec-valid `limit` values
|
||||
- `send` rejected an entire transaction when a single PDU didn't match a fixed event shape, instead of reporting failures per PDU
|
||||
|
||||
Also links every federation endpoint to its definition in the Matrix specification.
|
||||
5
.changeset/large-spies-raise.md
Normal file
5
.changeset/large-spies-raise.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Improves draft handling by discarding the stored draft as soon as a message is sent, instead of keeping it until the room is changed
|
||||
5
.changeset/lazy-hats-hammer.md
Normal file
5
.changeset/lazy-hats-hammer.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes long custom statuses being cut off without an ellipsis in the user status menu.
|
||||
5
.changeset/light-kiwis-share.md
Normal file
5
.changeset/light-kiwis-share.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Improves the sidebar to keep the room currently open listed under its category even while that category is collapsed, so it stays clear which room is being viewed
|
||||
5
.changeset/meteor-3-5.md
Normal file
5
.changeset/meteor-3-5.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Update Meteor to 3.5.2 and bump Node.js to 24.15.0 to match the new bundled runtime. Also bumps `isolated-vm` to 6.2.0 for Node.js 24 compatibility.
|
||||
6
.changeset/mobile-web-ui-tweaks.md
Normal file
6
.changeset/mobile-web-ui-tweaks.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@rocket.chat/meteor": patch
|
||||
"@rocket.chat/web-ui-registration": patch
|
||||
---
|
||||
|
||||
Improves the mobile web experience: the page background now follows the active theme so Safari no longer shows white strips in the overscroll/safe-area regions (and tints its toolbar) in dark mode; the login "Welcome to <workspace>" title is scaled down on small screens; focusing a field no longer triggers iOS Safari's auto zoom-in (inputs use a 16px minimum on mobile); the login email/username field no longer auto-capitalizes/auto-corrects; and the connection status bar layout no longer truncates its "Connect" button on narrow screens.
|
||||
5
.changeset/new-towns-wink.md
Normal file
5
.changeset/new-towns-wink.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes empty notifications when video conferences are created
|
||||
8
.changeset/odd-times-sleep.md
Normal file
8
.changeset/odd-times-sleep.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@rocket.chat/core-typings': minor
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/i18n': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Introduces custom, user-defined categories to the sidebar (Enterprise only). Users can create, rename, delete and reorder categories (menu-driven), and move rooms into them via the room context menu or the room header.
|
||||
9
.changeset/perf-quick-wins.md
Normal file
9
.changeset/perf-quick-wins.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@rocket.chat/random': patch
|
||||
'@rocket.chat/i18n': patch
|
||||
'@rocket.chat/license': patch
|
||||
'@rocket.chat/ui-client': patch
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Improves performance of several hot code paths without changing behavior: generates random IDs with a single `crypto.randomBytes` call instead of one per character, caches constant regular expressions used by the markdown/mention/autotranslate parsers instead of recompiling them for every message, skips the channel-mention database query for messages without channel mentions, deduplicates the room member count query when a message contains both `@all` and `@here`, and replaces linear array scans and spread-accumulators with Map/Set lookups in API response shaping (files, DM members, directory search and team listing).
|
||||
5
.changeset/proud-pears-wait.md
Normal file
5
.changeset/proud-pears-wait.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes users not being added to the default channels (such as `#general`) when they are assigned their first username, which affected the admin created by the setup wizard on a brand new workspace and OAuth, SAML and LDAP users that pick a username through the "Register Username" screen.
|
||||
10
.changeset/real-teeth-clean.md
Normal file
10
.changeset/real-teeth-clean.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
'@rocket.chat/media-calls': minor
|
||||
'@rocket.chat/model-typings': minor
|
||||
'@rocket.chat/core-typings': minor
|
||||
'@rocket.chat/models': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Started storing SIP Call Id on the media calls model
|
||||
Added an endpoint to retrieve media calls data
|
||||
6
.changeset/rest-chat-get-messages.md
Normal file
6
.changeset/rest-chat-get-messages.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Adds a new `POST /v1/chat.getMessages` endpoint to fetch several messages at once by id, including messages from different rooms. The request fails if any of the messages belongs to a room the caller cannot read.
|
||||
6
.changeset/rest-cloud-workspace-register-data.md
Normal file
6
.changeset/rest-cloud-workspace-register-data.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Adds a new `GET /v1/cloud.workspaceRegisterData` endpoint returning the base64 encoded workspace registration payload used by the offline cloud registration flow. It requires the `manage-cloud` permission.
|
||||
6
.changeset/rest-rooms-history-around.md
Normal file
6
.changeset/rest-rooms-history-around.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Adds an `aroundId` parameter to `GET /v1/rooms.history`, returning a window of messages centered on a given message instead of a page from one end of the room. This is what jumping to a quoted message, a search result or a thread message uses to load the surrounding conversation.
|
||||
6
.changeset/rest-rooms-history.md
Normal file
6
.changeset/rest-rooms-history.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Adds a new `GET /v1/rooms.history` endpoint to load a room's message history. Unlike the existing `channels.history`, `groups.history`, `im.history` and `dm.history` endpoints, it works with any room type through a single route, and can be used to read public channels anonymously when `Accounts_AllowAnonymousRead` is enabled.
|
||||
6
.changeset/rest-setup-wizard-parameters.md
Normal file
6
.changeset/rest-setup-wizard-parameters.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/rest-typings': minor
|
||||
'@rocket.chat/meteor': minor
|
||||
---
|
||||
|
||||
Adds a new `GET /v1/setupWizard.parameters` endpoint returning the settings flagged for the setup wizard along with a `serverAlreadyRegistered` flag.
|
||||
9
.changeset/room-toolbox-layout.md
Normal file
9
.changeset/room-toolbox-layout.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
'@rocket.chat/meteor': minor
|
||||
'@rocket.chat/ui-client': minor
|
||||
'@rocket.chat/i18n': minor
|
||||
---
|
||||
|
||||
Adds a configurable **Room Toolbox Layout**, available as an opt-in **Feature Preview** (My Account → Feature Preview → Room → **Room Toolbox Layout**). While the feature preview is off, the room header toolbox keeps its current behavior and the setting has no effect.
|
||||
|
||||
Admins can define the layout through the new workspace setting **Room Toolbox Layout** (`Room_Toolbox_Layout`) under **Admin → Settings → Layout → Room Header**, which is itself only shown when **Feature Preview** is enabled for the workspace. The setting value is validated against a JSON schema when saved, so a malformed configuration is rejected with an error instead of being silently ignored
|
||||
5
.changeset/session-resume-skeleton.md
Normal file
5
.changeset/session-resume-skeleton.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Shows the loading skeleton instead of flashing the login form while a stored session is being resumed
|
||||
6
.changeset/sidebar-stale-drafts-category.md
Normal file
6
.changeset/sidebar-stale-drafts-category.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/core-typings': patch
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes the removed `Drafts` sidebar group reappearing as an empty category on workspaces upgraded from a build that shipped it
|
||||
7
.changeset/storybook-dark-mode-fork.md
Normal file
7
.changeset/storybook-dark-mode-fork.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@rocket.chat/storybook-dark-mode': minor
|
||||
---
|
||||
|
||||
Declares `storybook` as a peer dependency, at `^9.0.0`. The addon has always imported from `storybook/preview-api`, `storybook/manager-api`, `storybook/theming` and several `storybook/internal/*` paths, but never said so, which left the requirement implicit and the internal APIs it relies on without a version contract.
|
||||
|
||||
Also stops shipping `.d.ts` and `.d.ts.map` files inside `dist/esm` and `dist/cjs`. Declarations were being emitted three times over and only the `dist/ts` copy is referenced by `types`, so the other two were dead weight in the tarball. Anything deep-importing types from `dist/esm` or `dist/cjs` — as opposed to resolving them through the package entry point — needs to use `dist/ts` instead.
|
||||
5
.changeset/swift-otters-listen.md
Normal file
5
.changeset/swift-otters-listen.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@rocket.chat/meteor": patch
|
||||
---
|
||||
|
||||
Fixes 'mark as unread' action not available for federated messages
|
||||
5
.changeset/tall-pandas-repeat.md
Normal file
5
.changeset/tall-pandas-repeat.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Aligns the rate limits of `spotlight`, `directory`, `chat.followMessage` and `chat.unfollowMessage` with the values defined in the DDP methods they replaced. They were falling back to the generic REST default of 10 requests per 60 seconds instead.
|
||||
5
.changeset/tasty-dingos-sit.md
Normal file
5
.changeset/tasty-dingos-sit.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes team deletion failing when the team's main room no longer exists. Such teams were left orphaned: hidden from the admin UI, still reserving their name, and impossible to remove through any supported path. Deleting a team now completes even when its main room is already gone, so a deletion interrupted midway can be finished by simply retrying it, and the team name becomes available again.
|
||||
7
.changeset/tidy-hoops-refuse.md
Normal file
7
.changeset/tidy-hoops-refuse.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
'@rocket.chat/models': patch
|
||||
'@rocket.chat/model-typings': patch
|
||||
---
|
||||
|
||||
Fixes Omnichannel rooms failing to register agent responses (and showing send errors on messages and file uploads that were actually delivered) when the room carried corrupted visitor activity data created by older app integrations
|
||||
5
.changeset/tired-camels-bow.md
Normal file
5
.changeset/tired-camels-bow.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Ensures the message composer is cleared after a slash command is executed.
|
||||
6
.changeset/ui-voip-call-widget-layout.md
Normal file
6
.changeset/ui-voip-call-widget-layout.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@rocket.chat/ui-voip': minor
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Improved the in-call voice widget: media elements no longer detach and re-attach when an unrelated device changes, so a shared screen or camera stops blinking whenever the microphone is muted or a device is switched.
|
||||
5
.changeset/warm-baboons-rescue.md
Normal file
5
.changeset/warm-baboons-rescue.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes ignored messages from ignored users in threads.
|
||||
5
.changeset/witty-beds-bow.md
Normal file
5
.changeset/witty-beds-bow.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@rocket.chat/meteor': patch
|
||||
---
|
||||
|
||||
Fixes direct messages addressed by username, such as the ones opened with **Reply in direct message**, not being found on the first lookup — which made opening a conversation cost an extra request and log an avoidable `Invalid Room` error.
|
||||
41
.devcontainer/Dockerfile
Normal file
41
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,41 @@
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/base:ubuntu
|
||||
|
||||
COPY package.json /tmp/package.json
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
apt-transport-https \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
curl \
|
||||
jq \
|
||||
libssl-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV NVM_DIR /usr/local/nvm
|
||||
RUN mkdir -p $NVM_DIR && \
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash && \
|
||||
bash -c ". $NVM_DIR/nvm.sh && nvm install $(jq -r '.engines.node' /tmp/package.json) && npm install -g yarn"
|
||||
|
||||
RUN echo "export NVM_DIR=$NVM_DIR" >> /etc/bash.bashrc && \
|
||||
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && \. \"$NVM_DIR/nvm.sh\"" >> /etc/bash.bashrc
|
||||
|
||||
ENV DENO_INSTALL=/usr/local/deno
|
||||
RUN mkdir -p $DENO_INSTALL && \
|
||||
curl -fsSL https://deno.land/install.sh | sh
|
||||
|
||||
ENV DENO_INSTALL="/usr/local/deno"
|
||||
ENV PATH="$DENO_INSTALL/bin:$PATH"
|
||||
|
||||
RUN echo 'export DENO_INSTALL="/usr/local/deno"' >> /etc/bash.bashrc && \
|
||||
echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /etc/bash.bashrc
|
||||
|
||||
ENV METEOR_INSTALL="/usr/local/meteor"
|
||||
ENV PATH="$METEOR_INSTALL/bin:$PATH"
|
||||
|
||||
RUN curl https://install.meteor.com/ | sh && \
|
||||
mv ~/.meteor $METEOR_INSTALL
|
||||
|
||||
RUN echo 'export METEOR_INSTALL="/usr/local/meteor"' >> /etc/bash.bashrc && \
|
||||
echo 'export PATH="$METEOR_INSTALL/bin:$PATH"' >> /etc/bash.bashrc
|
||||
|
||||
CMD ["bash"]
|
||||
18
.devcontainer/devcontainer.json
Normal file
18
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Rocket.Chat Gitpod",
|
||||
"build": {
|
||||
"context": "..",
|
||||
"dockerfile": "./Dockerfile"
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
||||
},
|
||||
"forwardPorts": [3000],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
19
.editorconfig
Normal file
19
.editorconfig
Normal file
@@ -0,0 +1,19 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{js,coffee,html,less,css,json}]
|
||||
indent_style = tab
|
||||
|
||||
[*.i18n.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
42
.github/CODEOWNERS
vendored
Normal file
42
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/packages/* @RocketChat/Architecture
|
||||
/packages/apps-engine/ @RocketChat/apps
|
||||
/packages/apps/ @RocketChat/apps
|
||||
/packages/core-typings/ @RocketChat/Architecture
|
||||
/packages/rest-typings/ @RocketChat/Architecture @RocketChat/backend
|
||||
/packages/ui-contexts/ @RocketChat/frontend
|
||||
/packages/eslint-config/ @RocketChat/Architecture
|
||||
/packages/livechat/ @RocketChat/frontend @RocketChat/Architecture
|
||||
/.vscode/ @RocketChat/Architecture
|
||||
/.github/ @RocketChat/Architecture
|
||||
/_templates/ @RocketChat/Architecture
|
||||
/apps/meteor/client/ @RocketChat/frontend
|
||||
/apps/meteor/tests/e2e @RocketChat/frontend
|
||||
/apps/meteor/tests/end-to-end @RocketChat/backend
|
||||
/apps/meteor/tests/unit/app @RocketChat/backend
|
||||
/apps/meteor/tests/unit/client @RocketChat/frontend
|
||||
/apps/meteor/tests/unit/server @RocketChat/backend
|
||||
/apps/meteor/app/apps/ @RocketChat/apps
|
||||
/apps/meteor/app/livechat @RocketChat/omnichannel
|
||||
/apps/meteor/app/file-upload @RocketChat/backend
|
||||
/apps/meteor/app/integrations @RocketChat/backend
|
||||
/apps/meteor/server @RocketChat/backend
|
||||
/apps/meteor/server/lib/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/server/hooks/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/server/api/v1/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/server/meteor-methods/omnichannel @RocketChat/omnichannel
|
||||
/packages/models @RocketChat/Architecture
|
||||
apps/meteor/server/startup/migrations @RocketChat/Architecture
|
||||
/apps/meteor/packages/rocketchat-livechat @RocketChat/omnichannel
|
||||
/apps/meteor/server/features/EmailInbox @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/apps/ @RocketChat/apps
|
||||
/apps/meteor/ee/tests/unit/server/apps/ @RocketChat/apps
|
||||
/apps/meteor/ee/server/lib/canned-responses @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/hooks/canned-responses @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/api/v1/canned-responses.ts @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/lib/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/hooks/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/api/v1/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/meteor-methods/saveCannedResponse.ts @RocketChat/omnichannel
|
||||
/apps/meteor/ee/server/meteor-methods/removeCannedResponse.ts @RocketChat/omnichannel
|
||||
/apps/meteor/client/omnichannel @RocketChat/omnichannel
|
||||
/apps/meteor/client/components/omnichannel @RocketChat/omnichannel
|
||||
27
.github/CONTRIBUTING.md
vendored
Normal file
27
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Contributing to Rocket.Chat
|
||||
|
||||
**First off, thanks for taking the time to contribute! :tada::+1:**
|
||||
|
||||
> There are many ways to contribute to Rocket.Chat even if you're not technical or a developer:
|
||||
>
|
||||
> * Email us at marketing@rocket.chat to tell us how much you love the project
|
||||
> * Write about us in your blogs
|
||||
> * Fix some small typos in our [documentation](https://docs.rocket.chat/contributing)
|
||||
> * Become our [GitHub sponsor](https://github.com/sponsors/RocketChat)
|
||||
> * Tell others about us and help us spread the word
|
||||
>
|
||||
> Every bit of contribution is appreciated 🙂 thank you!
|
||||
|
||||
The following is a set of guidelines for contributing to Rocket.Chat, which are hosted in the [Rocket.Chat Organization](https://github.com/RocketChat) on GitHub.
|
||||
|
||||
__Note:__ If there's a feature you'd like, there's a bug you'd like to fix, or you'd just like to get involved please raise an issue and start a conversation. We'll help as much as we can so you can get contributing - although we may not always be able to respond right away :)
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
Check out our Handbook for the [Development Guidelines](https://handbook.rocket.chat/space/RnD/359891343/%F0%9F%8C%90+Development+Guidelines) on how to set up your environment, do code, test and push your code. There you find our patterns on how to compose your Pull Requests' titles to have your contribution accepted.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
To have your contribution accepted you must sign our [Contributor License Agreement](https://cla-assistant.io/RocketChat/Rocket.Chat). In case you submit a Pull Request before signing the CLA GitHub will alert you with a new comment asking you to sign and will block the Pull Request from being merged by us.
|
||||
|
||||
Please review and sign our CLA at https://cla-assistant.io/RocketChat/Rocket.Chat
|
||||
59
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
59
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
|
||||
Please see our guide for opening issues: https://developer.rocket.chat/rocket.chat/contribute-to-rocket.chat/ways-to-contribute/report-bugs
|
||||
|
||||
If you have questions or are looking for help/support please see: https://rocket.chat/docs/getting-support
|
||||
|
||||
If you are experiencing a bug please search our issues to be sure it is not already present: https://github.com/RocketChat/Rocket.Chat/issues
|
||||
|
||||
-->
|
||||
|
||||
### Description:
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
### Steps to reproduce:
|
||||
|
||||
1. <!-- Go to '...' -->
|
||||
2. <!-- Click on '....' -->
|
||||
3. <!-- and so on... -->
|
||||
|
||||
### Expected behavior:
|
||||
|
||||
<!-- What you expect to happen -->
|
||||
|
||||
### Actual behavior:
|
||||
|
||||
<!-- What actually happens with SCREENSHOT, if applicable -->
|
||||
|
||||
### Server Setup Information:
|
||||
|
||||
- Version of Rocket.Chat Server:
|
||||
- License Type:
|
||||
- Number of Users:
|
||||
- Operating System:
|
||||
- Deployment Method: <!-- snap/docker/tar/etc -->
|
||||
- Number of Running Instances:
|
||||
- DB Replicaset Oplog:
|
||||
- NodeJS Version:
|
||||
- MongoDB Version:
|
||||
|
||||
### Client Setup Information
|
||||
|
||||
- Desktop App or Browser Version:
|
||||
- Operating System:
|
||||
|
||||
### Additional context
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
|
||||
### Relevant logs:
|
||||
|
||||
<!-- Logs from both SERVER and BROWSER -->
|
||||
<!-- For more information about collecting logs please see: https://rocket.chat/docs/contributing/reporting-issues#gathering-logs -->
|
||||
59
.github/ISSUE_TEMPLATE/release.md
vendored
Normal file
59
.github/ISSUE_TEMPLATE/release.md
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
name: Release
|
||||
about: Internal release checklist template
|
||||
|
||||
---
|
||||
|
||||
# Release {version}
|
||||
We are releasing a new version, this issue will keep track of the progress between the first release candidate (20th of each month) to the final release (27th of each month).
|
||||
|
||||
Beginning on the 20th of each month, we will start the release process which ends 7 days later (the 27th). During this period of time, we will enter a "Feature Freeze". This Feature Freeze means that we will only be merging pull requests which fix bugs and not ones that add new features.
|
||||
|
||||
When you find a bug that is a regression, please open a new issue and link it to this one.
|
||||
|
||||
|
||||
## Before Release - Preparation - 1 business day before the day 20th
|
||||
- [x] Create the issue to track the release progress
|
||||
- [ ] Define the highlights from release PRs as a suggestion to be included on Blog Post <!-- link to the website's issue -->
|
||||
- [ ] Talk to the Marketing Team about starting the release Blog Post
|
||||
- [ ] Talk to the Documentation Team about ensuring the Docs are up to date and all pull requests are merged
|
||||
- [ ] Sync translations from [LingoHub](https://translate.lingohub.com/rocketchat/rocket-dot-chat/dashboard)
|
||||
|
||||
## Release Candidate 1 - On the 20th
|
||||
- [ ] Execute action `Release Candidate` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`)
|
||||
- [ ] Check if `release-candidate` branch was published
|
||||
- [ ] Check if the tag was published and contains the history
|
||||
- [ ] Ensure the build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat)
|
||||
- [ ] Ensure the image was sent to [Docker Hub](https://hub.docker.com/r/rocketchat/rocket.chat/tags/)
|
||||
|
||||
<!-- Copy following block for next release candidates
|
||||
## Release Candidate {release-candidate-version} - On the {day}
|
||||
- [ ] Execute action `Release Candidate` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`)
|
||||
- [ ] Check if `release-candidate` branch was published
|
||||
- [ ] Check if the tag was published and contains the history
|
||||
- [ ] Ensure the build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat)
|
||||
- [ ] Ensure the image was sent to [Docker Hub](https://hub.docker.com/r/rocketchat/rocket.chat/tags/)
|
||||
-->
|
||||
|
||||
## Final Release - On the 27th
|
||||
- [ ] Execute action `Final Release` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`)
|
||||
- [ ] Check if `release-{version}` branch was published
|
||||
- [ ] Check if the release was created as **draft** and contains the history
|
||||
- [ ] Check if the release Pull Request was created and contains the history
|
||||
- [ ] Ensure the **Pull Request** build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat)
|
||||
- [ ] When the build is passing ask for Pull Request approval
|
||||
- [ ] When approved, merge it!
|
||||
- [ ] Ensure the **Tag** build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat)
|
||||
- [ ] Ensure the image was sent to [Docker Hub](https://hub.docker.com/r/rocketchat/rocket.chat/tags/)
|
||||
- [ ] After all edit the release/tag and publish it
|
||||
|
||||
## After Release - Conclusion - 1 business day after the 27th
|
||||
- [ ] Ensure all of the related issues were closed
|
||||
- [ ] Determine if all of the related issues were correctly assigned to this version's milestone
|
||||
- [ ] Get an update from Marketing Team about the release of Blog Post
|
||||
- [ ] Check with the Documentation Team about the Docs release
|
||||
- [ ] Sync develop
|
||||
- [ ] Execute action `Develop Sync` via [Houston CLI](https://github.com/RocketChat/Rocket.Chat.Houston) (`houston release`)
|
||||
- [ ] Ensure the **Pull Request** build is passing on [CircleCI](https://circleci.com/gh/RocketChat/Rocket.Chat)
|
||||
- [ ] When the build has passed, ask for approval and wait
|
||||
- [ ] Merge Sync PR
|
||||
39
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
39
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<!-- This is a pull request template, you do not need to uncomment or remove the comments, they won't show up in the PR text. -->
|
||||
|
||||
<!-- Your Pull Request name should start with one of the following tags
|
||||
feat: Adding a new feature
|
||||
refactor: A code change that doesn't change behavior (it doesn't add anything and doesn't fix anything)
|
||||
fix: For bug fixes that affect the end-user
|
||||
chore: For small tasks
|
||||
docs: For documentation
|
||||
ci: For updating CI configuration
|
||||
test: For adding tests
|
||||
i18n: For updating any translations
|
||||
regression: Issues created/reported/fixed during the development phase. kind of problem that never existed in production and that we don't need to list in a changelog for the end user
|
||||
-->
|
||||
|
||||
<!-- Checklist!!! If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.
|
||||
- I have read the Contributing Guide - https://github.com/RocketChat/Rocket.Chat/blob/develop/.github/CONTRIBUTING.md#contributing-to-rocketchat doc
|
||||
- I have signed the CLA - https://cla-assistant.io/RocketChat/Rocket.Chat
|
||||
- Lint and unit tests pass locally with my changes
|
||||
- I have added tests that prove my fix is effective or that my feature works (if applicable)
|
||||
- I have added necessary documentation (if applicable)
|
||||
- Any dependent changes have been merged and published in downstream modules
|
||||
-->
|
||||
|
||||
## Proposed changes (including videos or screenshots)
|
||||
<!--
|
||||
Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.
|
||||
If it fixes a bug or resolves a feature request, be sure to link to that issue below.
|
||||
This description won't be displayed to our end users in the release notes, so feel free to add as much technical context as needed.
|
||||
If the changes introduced in this pull request must be presented in the release notes, make sure to add a changeset file. Check our guidelines for adding a changeset to your pull request: https://developer.rocket.chat/contribute-to-rocket.chat/modes-of-contribution/participate-in-rocket.chat-development/development-workflow#4.-adding-changeset-to-your-pull-request
|
||||
-->
|
||||
|
||||
## Issue(s)
|
||||
<!-- Link the issues being closed by or related to this PR. For example, you can use #594 if this PR closes issue number 594 -->
|
||||
|
||||
## Steps to test or reproduce
|
||||
<!-- Mention how you would reproduce the bug if not mentioned on the issue page already. Also mention which screens are going to have the changes if applicable -->
|
||||
|
||||
## Further comments
|
||||
<!-- If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... -->
|
||||
17
.github/actionlint-matcher.json
vendored
Normal file
17
.github/actionlint-matcher.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "actionlint",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 4,
|
||||
"code": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
3
.github/actionlint.yaml
vendored
Normal file
3
.github/actionlint.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
paths:
|
||||
.github/workflows/**/*.yml:
|
||||
ignore: ['file "dist/index\.js" does not exist in .*/packages/release-action']
|
||||
246
.github/actions/build-docker/action.yml
vendored
Normal file
246
.github/actions/build-docker/action.yml
vendored
Normal file
@@ -0,0 +1,246 @@
|
||||
name: 'Build Docker'
|
||||
description: 'Build Docker images for Rocket.Chat and related services'
|
||||
|
||||
inputs:
|
||||
CR_USER:
|
||||
required: true
|
||||
description: 'GitHub Container Registry username'
|
||||
CR_PAT:
|
||||
required: true
|
||||
description: 'GitHub Container Registry Personal Access Token'
|
||||
DOCKER_USER:
|
||||
required: false
|
||||
description: 'DockerHub username (required for FIPS builds to pull private base image)'
|
||||
DOCKER_PASS:
|
||||
required: false
|
||||
description: 'DockerHub password (required for FIPS builds to pull private base image)'
|
||||
deno-version:
|
||||
required: true
|
||||
description: 'Deno version'
|
||||
arch:
|
||||
required: false
|
||||
description: 'Architecture'
|
||||
default: 'arm64'
|
||||
service:
|
||||
required: false
|
||||
description: 'Container to build'
|
||||
publish-image:
|
||||
required: false
|
||||
description: 'Publish image'
|
||||
default: 'true'
|
||||
setup-docker:
|
||||
required: false
|
||||
description: 'Setup Docker'
|
||||
default: 'true'
|
||||
type:
|
||||
required: false
|
||||
description: 'production, coverage, or fips'
|
||||
default: 'coverage'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Login to GitHub Container Registry
|
||||
if: inputs.publish-image == 'true' && github.actor != 'dependabot[bot]' && (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop')
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ inputs.CR_USER }}
|
||||
password: ${{ inputs.CR_PAT }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
# FIPS base image (rocketchat/dhi-node) lives in a private DockerHub repo and requires auth to pull.
|
||||
if: inputs.type == 'fips' && (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.event_name == 'merge_group' || github.ref == 'refs/heads/develop')
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
|
||||
with:
|
||||
username: ${{ inputs.DOCKER_USER }}
|
||||
password: ${{ inputs.DOCKER_PASS }}
|
||||
|
||||
- name: Restore meteor build
|
||||
if: inputs.service == 'rocketchat'
|
||||
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
||||
with:
|
||||
name: build-${{ inputs.type == 'fips' && ((github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production') || inputs.type }}
|
||||
path: /tmp/build
|
||||
|
||||
- name: Unpack meteor build
|
||||
if: inputs.service == 'rocketchat'
|
||||
shell: bash
|
||||
run: |
|
||||
cd /tmp/build
|
||||
tar xzf Rocket.Chat.tar.gz
|
||||
rm Rocket.Chat.tar.gz
|
||||
|
||||
- name: Set up Docker
|
||||
if: inputs.setup-docker == 'true'
|
||||
uses: docker/setup-docker-action@e43656e248c0bd0647d3f5c195d116aacf6fcaf4 # v4.7.0
|
||||
with:
|
||||
daemon-config: |
|
||||
{
|
||||
"debug": false,
|
||||
"features": {
|
||||
"containerd-snapshotter": true
|
||||
}
|
||||
}
|
||||
|
||||
# Microservice images build from a pruned, self-contained context (out/<service>)
|
||||
# produced by `turbo prune`, instead of a hand-maintained list of COPY lines.
|
||||
# The rocketchat (Meteor) image is a prebuilt bundle and is staged separately above.
|
||||
- name: Stage service build context
|
||||
if: inputs.service != 'rocketchat'
|
||||
shell: bash
|
||||
env:
|
||||
INPUT_SERVICE: ${{ inputs.service }}
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
# The Docker SERVICE arg (folder under ee/apps) lives in the compose build args;
|
||||
# the compose service name (INPUT_SERVICE) can differ (e.g. ddp-streamer-service).
|
||||
SERVICE_DIR=$(docker compose -f docker-compose-ci.yml config --format json 2>/dev/null | jq -r --arg s "$INPUT_SERVICE" '.services[$s].build.args.SERVICE')
|
||||
PKG_NAME=$(node -p "require('./ee/apps/${SERVICE_DIR}/package.json').name")
|
||||
TURBO_VERSION=$(node -p "require('./package.json').devDependencies.turbo")
|
||||
|
||||
rm -rf "out/${SERVICE_DIR}"
|
||||
|
||||
# `turbo prune` derives the exact workspace dependency closure for the service — no
|
||||
# hand-maintained list. --use-gitignore=false also captures the gitignored build output
|
||||
# we need (dist/, generated definition/), at the cost of dragging in node_modules/.turbo,
|
||||
# which we strip below; `yarn workspaces focus --production` rebuilds node_modules in-image.
|
||||
npx -y "turbo@${TURBO_VERSION}" prune "$PKG_NAME" --skip-infer --use-gitignore=false --out-dir "out/${SERVICE_DIR}"
|
||||
|
||||
find "out/${SERVICE_DIR}" \( -name node_modules -o -name .turbo \) -type d -prune -exec rm -rf {} +
|
||||
|
||||
- name: Build Docker images
|
||||
shell: bash
|
||||
env:
|
||||
DENO_VERSION: ${{ inputs.deno-version }}
|
||||
INPUT_ARCH: ${{ inputs.arch }}
|
||||
INPUT_SERVICE: ${{ inputs.service }}
|
||||
INPUT_PUBLISH_IMAGE: ${{ inputs.publish-image }}
|
||||
INPUT_TYPE: ${{ inputs.type }}
|
||||
GITHUB_RUN_ID: ${{ github.run_id }}
|
||||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
GITHUB_EVENT_NAME: ${{ github.event_name }}
|
||||
GITHUB_REF: ${{ github.ref }}
|
||||
run: |
|
||||
set -o xtrace
|
||||
compose_fips_override=''
|
||||
if [[ "$INPUT_TYPE" == 'fips' ]]; then
|
||||
compose_fips_override='-f docker-compose-ci.fips.yml'
|
||||
fi
|
||||
|
||||
# Removes unnecessary swc cores and sharp binaries to reduce image size
|
||||
swc_arch='x64'
|
||||
if [[ "$INPUT_SERVICE" == 'rocketchat' ]]; then
|
||||
if [[ "$INPUT_ARCH" == 'arm64' ]]; then
|
||||
swc_arch='arm64'
|
||||
fi
|
||||
|
||||
find /tmp/build/bundle/programs/server/npm/node_modules/@img -type d -name 'sharp-*' -not -name "*-linuxmusl-${swc_arch}" -exec rm -rf {} +
|
||||
|
||||
find /tmp/build/bundle/programs/server/npm/node_modules/@napi-rs -type d -name 'pinyin-linux-*' -not -name "*-linux-${swc_arch}-*" -exec rm -rf {} +
|
||||
|
||||
find /tmp/build/bundle/programs/server/npm/node_modules/@esbuild -type d -name 'linux-*' -not -name "*-${swc_arch}" -exec rm -rf {} +
|
||||
|
||||
find /tmp/build/bundle/programs/server/npm/node_modules/@rocket.chat/apps/node_modules/@esbuild -type d -name 'linux-*' -not -name "*-${swc_arch}" -exec rm -rf {} +
|
||||
fi
|
||||
|
||||
if [[ "$INPUT_PUBLISH_IMAGE" == 'true' ]]; then
|
||||
LOAD_OR_PUSH="--push"
|
||||
else
|
||||
LOAD_OR_PUSH="--load"
|
||||
fi
|
||||
|
||||
# Get image name from docker-compose-ci.yml since rocketchat image is different from service name (rocket.chat)
|
||||
IMAGE=$(docker compose -f docker-compose-ci.yml $compose_fips_override config --format json 2>/dev/null | jq -r --arg s "$INPUT_SERVICE" '.services[$s].image')
|
||||
|
||||
docker buildx bake \
|
||||
-f docker-compose-ci.yml $compose_fips_override \
|
||||
${LOAD_OR_PUSH} \
|
||||
--allow=fs.read=/tmp/build \
|
||||
--set "*.tags+=${IMAGE}-gha-run-${GITHUB_RUN_ID}" \
|
||||
--set "*.labels.org.opencontainers.image.description=Build run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" \
|
||||
--set "*.labels.org.opencontainers.image.source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \
|
||||
--set "*.platform=linux/${INPUT_ARCH}" \
|
||||
--set *.cache-from=type=gha \
|
||||
--set *.cache-to=type=gha,mode=max \
|
||||
--provenance=false \
|
||||
--sbom=false \
|
||||
--metadata-file "/tmp/meta.json" \
|
||||
"$INPUT_SERVICE"
|
||||
|
||||
echo "Contents of /tmp/meta.json:"
|
||||
cat /tmp/meta.json
|
||||
|
||||
if [[ "$INPUT_PUBLISH_IMAGE" == 'true' ]]; then
|
||||
SERVICE_SUFFIX=''
|
||||
if [[ "$INPUT_SERVICE" == 'rocketchat' && "$INPUT_TYPE" == 'coverage' ]] && [[ "$GITHUB_EVENT_NAME" == 'release' || "$GITHUB_REF" == 'refs/heads/develop' ]]; then
|
||||
SERVICE_SUFFIX='-cov'
|
||||
elif [[ "$INPUT_TYPE" == 'fips' ]]; then
|
||||
SERVICE_SUFFIX='-fips'
|
||||
fi
|
||||
|
||||
mkdir -p "/tmp/manifests/${INPUT_SERVICE}${SERVICE_SUFFIX}/${INPUT_ARCH}"
|
||||
|
||||
# Get digest and image info
|
||||
DIGEST=$(jq -r --arg service "$INPUT_SERVICE" '.[$service].["containerimage.digest"]' "/tmp/meta.json")
|
||||
IMAGE_NO_TAG=$(echo "$IMAGE" | sed 's/:.*$//')
|
||||
FULL_IMAGE="${IMAGE_NO_TAG}@${DIGEST}"
|
||||
|
||||
echo "Inspecting image: $FULL_IMAGE"
|
||||
|
||||
# Inspect the image and save complete manifest with sizes (using -v for verbose)
|
||||
docker manifest inspect -v "$FULL_IMAGE" > "/tmp/manifests/${INPUT_SERVICE}${SERVICE_SUFFIX}/${INPUT_ARCH}/manifest.json"
|
||||
|
||||
echo "Saved manifest to /tmp/manifests/${INPUT_SERVICE}${SERVICE_SUFFIX}/${INPUT_ARCH}/manifest.json"
|
||||
cat "/tmp/manifests/${INPUT_SERVICE}${SERVICE_SUFFIX}/${INPUT_ARCH}/manifest.json" | jq '.'
|
||||
fi
|
||||
|
||||
- name: Save Docker image as artifact
|
||||
if: inputs.publish-image == 'false' && inputs.arch == 'amd64'
|
||||
shell: bash
|
||||
env:
|
||||
SERVICE: ${{ inputs.service }}
|
||||
ARCH: ${{ inputs.arch }}
|
||||
TYPE: ${{ inputs.type }}
|
||||
run: |
|
||||
set -o xtrace
|
||||
compose_fips_override=''
|
||||
if [[ "$TYPE" == 'fips' ]]; then
|
||||
compose_fips_override='-f docker-compose-ci.fips.yml'
|
||||
fi
|
||||
|
||||
# Get image name from docker-compose-ci.yml
|
||||
IMAGE=$(docker compose -f docker-compose-ci.yml $compose_fips_override config --format json 2>/dev/null | jq -r --arg s "$SERVICE" '.services[$s].image')
|
||||
|
||||
# Create directory for image archives
|
||||
mkdir -p /tmp/docker-images
|
||||
|
||||
# Save the image to a tar file
|
||||
docker save "${IMAGE}" -o "/tmp/docker-images/${SERVICE}-${ARCH}-${TYPE}.tar"
|
||||
|
||||
echo "Saved image to /tmp/docker-images/${SERVICE}-${ARCH}-${TYPE}.tar"
|
||||
ls -lh /tmp/docker-images/
|
||||
|
||||
- name: Upload Docker image artifact
|
||||
if: inputs.publish-image == 'false' && inputs.arch == 'amd64'
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: docker-image-${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }}
|
||||
path: /tmp/docker-images/${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }}.tar
|
||||
retention-days: 1
|
||||
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
if: inputs.publish-image == 'true'
|
||||
with:
|
||||
name: manifests-${{ inputs.service }}-${{ inputs.arch }}-${{ inputs.type }}
|
||||
path: /tmp/manifests
|
||||
retention-days: 5
|
||||
|
||||
- name: Clean up temporary files
|
||||
if: inputs.service == 'rocketchat'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo rm -rf /tmp/build
|
||||
581
.github/actions/docker-image-size-tracker/action.yml
vendored
Normal file
581
.github/actions/docker-image-size-tracker/action.yml
vendored
Normal file
@@ -0,0 +1,581 @@
|
||||
name: 'Docker Image Size Tracker'
|
||||
description: 'Track and report Docker image sizes in Pull Requests'
|
||||
author: 'Rocket.Chat'
|
||||
|
||||
inputs:
|
||||
github-token:
|
||||
description: 'GitHub token for commenting on PRs'
|
||||
required: true
|
||||
ci-pat:
|
||||
description: 'GitHub token for committing to history branch'
|
||||
required: true
|
||||
registry:
|
||||
description: 'Container registry (e.g., ghcr.io)'
|
||||
required: false
|
||||
default: 'ghcr.io'
|
||||
repository:
|
||||
description: 'Repository name (e.g., rocketchat)'
|
||||
required: true
|
||||
tag:
|
||||
description: 'Image tag to measure'
|
||||
required: true
|
||||
baseline-tag:
|
||||
description: 'Baseline tag to compare against'
|
||||
required: false
|
||||
default: 'develop'
|
||||
platform:
|
||||
description: 'Platform architecture to compare (amd64 or arm64)'
|
||||
required: false
|
||||
default: 'amd64'
|
||||
size-thresholds:
|
||||
description: 'Optional JSON: per-image trigger thresholds. Only comment when an image increase exceeds its threshold. Example: {"rocketchat":{"mb":50,"percent":5},"omnichannel":{"mb":10,"percent":2}}'
|
||||
required: false
|
||||
default: ''
|
||||
fail-thresholds:
|
||||
description: 'Optional JSON: per-image fail thresholds. Task fails when an image increase exceeds its threshold (mb and/or percent). Example: {"rocketchat":{"mb":100,"percent":15}}'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
outputs:
|
||||
total-size:
|
||||
description: 'Total size in bytes'
|
||||
value: ${{ steps.measure.outputs.total-size }}
|
||||
size-diff:
|
||||
description: 'Size difference in bytes'
|
||||
value: ${{ steps.compare.outputs.size-diff }}
|
||||
size-diff-percent:
|
||||
description: 'Size difference percentage'
|
||||
value: ${{ steps.compare.outputs.size-diff-percent }}
|
||||
comment-triggered:
|
||||
description: 'Whether to post PR comment (only when size is bigger and thresholds met)'
|
||||
value: ${{ steps.compare.outputs.comment-triggered }}
|
||||
failed:
|
||||
description: 'True if image size exceeded fail-thresholds'
|
||||
value: ${{ steps.compare.outputs.failed }}
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Download manifests
|
||||
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
||||
with:
|
||||
pattern: manifests-*
|
||||
path: /tmp/manifests
|
||||
merge-multiple: true
|
||||
|
||||
- name: Measure image sizes from artifacts
|
||||
id: measure
|
||||
shell: bash
|
||||
env:
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
echo "Reading image sizes from build artifacts for platform: $PLATFORM"
|
||||
|
||||
declare -A sizes
|
||||
declare -a services_list
|
||||
total=0
|
||||
|
||||
# Loop through service directories (same as publish workflow)
|
||||
shopt -s nullglob
|
||||
for service_dir in /tmp/manifests/*; do
|
||||
[[ -d "$service_dir" ]] || continue
|
||||
service="$(basename "$service_dir")"
|
||||
|
||||
echo "Processing service: $service"
|
||||
services_list+=("$service")
|
||||
|
||||
size=0
|
||||
# Read only the specified platform architecture
|
||||
manifest_file="$service_dir/$PLATFORM/manifest.json"
|
||||
if [[ -f "$manifest_file" ]]; then
|
||||
# docker manifest inspect -v puts the manifest under SchemaV2Manifest
|
||||
# (Docker schema2 images) or OCIManifest (OCI images, which buildx
|
||||
# produces by default). Coalesce so both formats are read.
|
||||
config_size=$(jq -r '(.SchemaV2Manifest // .OCIManifest).config.size // 0' "$manifest_file")
|
||||
layers_size=$(jq '[(.SchemaV2Manifest // .OCIManifest).layers[]?.size // 0] | add // 0' "$manifest_file")
|
||||
size=$((config_size + layers_size))
|
||||
|
||||
echo " → Found $manifest_file: $size bytes (config: $config_size, layers: $layers_size)"
|
||||
else
|
||||
echo " ⚠ Manifest not found for platform $PLATFORM: $manifest_file"
|
||||
fi
|
||||
|
||||
sizes[$service]=$size
|
||||
total=$((total + size))
|
||||
done
|
||||
|
||||
echo "Total size (all services, $PLATFORM only): $total bytes"
|
||||
echo "total-size=$total" >> $GITHUB_OUTPUT
|
||||
|
||||
# Save to JSON
|
||||
echo "{" > current-sizes.json
|
||||
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> current-sizes.json
|
||||
echo " \"tag\": \"$TAG\"," >> current-sizes.json
|
||||
echo " \"total\": $total," >> current-sizes.json
|
||||
echo " \"services\": {" >> current-sizes.json
|
||||
|
||||
first=true
|
||||
for service in "${services_list[@]}"; do
|
||||
if [[ "$first" == "true" ]]; then
|
||||
first=false
|
||||
else
|
||||
echo "," >> current-sizes.json
|
||||
fi
|
||||
echo " \"$service\": ${sizes[$service]}" >> current-sizes.json
|
||||
done
|
||||
|
||||
echo " }" >> current-sizes.json
|
||||
echo "}" >> current-sizes.json
|
||||
|
||||
echo "Current sizes saved:"
|
||||
cat current-sizes.json
|
||||
|
||||
# Save services list for baseline measurement
|
||||
printf '%s\n' "${services_list[@]}" > /tmp/services-list.txt
|
||||
|
||||
- name: Measure baseline
|
||||
id: baseline
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
env:
|
||||
REGISTRY: ${{ inputs.registry }}
|
||||
ORG: ${{ inputs.repository }}
|
||||
TAG: ${{ inputs.baseline-tag }}
|
||||
PLATFORM: ${{ inputs.platform }}
|
||||
run: |
|
||||
echo "Measuring baseline: $REGISTRY/$ORG/*:$TAG (platform: $PLATFORM)"
|
||||
|
||||
declare -A sizes
|
||||
declare -a services_list
|
||||
total=0
|
||||
|
||||
# Read services list from current measurement
|
||||
while IFS= read -r service; do
|
||||
services_list+=("$service")
|
||||
|
||||
# Map service name to image name (handle rocketchat -> rocket.chat)
|
||||
if [[ "$service" == "rocketchat" ]] || [[ "$service" == "rocketchat-cov" ]]; then
|
||||
image_name="rocket.chat"
|
||||
[[ "$service" == "rocketchat-cov" ]] && image_name="rocket.chat-cov"
|
||||
else
|
||||
image_name="$service"
|
||||
fi
|
||||
|
||||
image="$REGISTRY/$ORG/$image_name:$TAG"
|
||||
echo " → Inspecting $image"
|
||||
|
||||
size=0
|
||||
if manifest=$(docker manifest inspect "$image" 2>/dev/null); then
|
||||
# Check if it's a manifest list (multi-arch)
|
||||
if echo "$manifest" | jq -e '.manifests' > /dev/null 2>&1; then
|
||||
# Manifest list - find the specified platform
|
||||
echo " → Multi-arch manifest detected, filtering for $PLATFORM"
|
||||
platform_digest=$(echo "$manifest" | jq -r --arg arch "$PLATFORM" '.manifests[] | select(.platform.architecture == $arch) | .digest' | head -1)
|
||||
|
||||
if [[ -n "$platform_digest" ]]; then
|
||||
echo " → Inspecting $PLATFORM platform: $platform_digest"
|
||||
if platform_manifest=$(docker manifest inspect "$REGISTRY/$ORG/$image_name@$platform_digest" 2>/dev/null); then
|
||||
config_size=$(echo "$platform_manifest" | jq -r '.config.size // 0')
|
||||
layers_size=$(echo "$platform_manifest" | jq '[.layers[]?.size // 0] | add // 0')
|
||||
size=$((config_size + layers_size))
|
||||
echo " → Size: $size bytes"
|
||||
fi
|
||||
else
|
||||
echo " ⚠ Platform $PLATFORM not found in manifest"
|
||||
fi
|
||||
else
|
||||
# Single arch manifest
|
||||
config_size=$(echo "$manifest" | jq -r '.config.size // 0')
|
||||
layers_size=$(echo "$manifest" | jq '[.layers[]?.size // 0] | add // 0')
|
||||
size=$((config_size + layers_size))
|
||||
fi
|
||||
fi
|
||||
|
||||
sizes[$service]=$size
|
||||
total=$((total + size))
|
||||
done < /tmp/services-list.txt
|
||||
|
||||
echo "baseline-total=$total" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "{" > baseline-sizes.json
|
||||
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> baseline-sizes.json
|
||||
echo " \"tag\": \"$TAG\"," >> baseline-sizes.json
|
||||
echo " \"total\": $total," >> baseline-sizes.json
|
||||
echo " \"services\": {" >> baseline-sizes.json
|
||||
|
||||
first=true
|
||||
for service in "${services_list[@]}"; do
|
||||
if [[ "$first" == "true" ]]; then
|
||||
first=false
|
||||
else
|
||||
echo "," >> baseline-sizes.json
|
||||
fi
|
||||
echo " \"$service\": ${sizes[$service]}" >> baseline-sizes.json
|
||||
done
|
||||
|
||||
echo " }" >> baseline-sizes.json
|
||||
echo "}" >> baseline-sizes.json
|
||||
|
||||
- name: Setup history storage
|
||||
id: history
|
||||
shell: bash
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Create a separate worktree for history branch
|
||||
mkdir -p /tmp/history-worktree
|
||||
|
||||
# Try to fetch history branch
|
||||
if git ls-remote --heads origin image-size-history | grep -q image-size-history; then
|
||||
git fetch origin image-size-history
|
||||
git worktree add /tmp/history-worktree image-size-history
|
||||
else
|
||||
# Create orphan branch for history in worktree
|
||||
git worktree add --detach /tmp/history-worktree
|
||||
cd /tmp/history-worktree
|
||||
git checkout --orphan image-size-history
|
||||
git rm -rf . 2>/dev/null || true
|
||||
mkdir -p history
|
||||
echo "# Image Size History" > README.md
|
||||
echo "This branch stores historical image size data for tracking" >> README.md
|
||||
git add README.md
|
||||
git commit -m "Initialize image size history"
|
||||
git push origin image-size-history
|
||||
cd -
|
||||
fi
|
||||
|
||||
mkdir -p /tmp/history-worktree/history
|
||||
|
||||
- name: Load historical data
|
||||
shell: bash
|
||||
run: |
|
||||
# Load last 30 measurements and group by day (keep only last entry per day)
|
||||
echo "[]" > history-data.json
|
||||
if [[ -d /tmp/history-worktree/history ]]; then
|
||||
jq -s '.' /tmp/history-worktree/history/*.json 2>/dev/null | jq '
|
||||
sort_by(.timestamp) |
|
||||
group_by(.timestamp[0:10]) |
|
||||
map(.[-1]) |
|
||||
.[-30:]
|
||||
' > history-data.json || echo "[]" > history-data.json
|
||||
fi
|
||||
|
||||
count=$(jq 'length' history-data.json)
|
||||
echo "Loaded $count historical measurements (one per day)"
|
||||
|
||||
- name: Save current measurement to history
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
shell: bash
|
||||
env:
|
||||
CI_PAT: ${{ inputs.ci-pat }}
|
||||
run: |
|
||||
timestamp=$(date -u +%Y%m%d-%H%M%S)
|
||||
commit_sha="${{ github.sha }}"
|
||||
|
||||
# Add commit info to current measurement
|
||||
jq --arg sha "$commit_sha" '. + {commit: $sha}' current-sizes.json > "/tmp/history-worktree/history/${timestamp}.json"
|
||||
|
||||
cd /tmp/history-worktree
|
||||
git add "history/${timestamp}.json"
|
||||
git commit -m "Add measurement for ${timestamp} (${commit_sha:0:7})"
|
||||
git config --global user.email "ci@rocket.chat"
|
||||
git config --global user.name "rocketchat-ci[bot]"
|
||||
git config --global url.https://$CI_PAT@github.com/.insteadOf https://github.com/
|
||||
git push origin image-size-history
|
||||
cd -
|
||||
|
||||
echo "Saved measurement to history"
|
||||
|
||||
- name: Compare and generate report
|
||||
id: compare
|
||||
shell: bash
|
||||
env:
|
||||
SIZE_THRESHOLDS: ${{ inputs.size-thresholds }}
|
||||
FAIL_THRESHOLDS: ${{ inputs.fail-thresholds }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
BASELINE_TAG: ${{ inputs.baseline-tag }}
|
||||
run: |
|
||||
current_total=$(jq -r '.total' current-sizes.json)
|
||||
|
||||
if [[ ! -f baseline-sizes.json ]]; then
|
||||
echo "No baseline available"
|
||||
echo "size-diff=0" >> $GITHUB_OUTPUT
|
||||
echo "size-diff-percent=0" >> $GITHUB_OUTPUT
|
||||
echo "comment-triggered=false" >> $GITHUB_OUTPUT
|
||||
|
||||
cat > report.md << 'EOF'
|
||||
# 📦 Docker Image Size Report
|
||||
|
||||
**Status:** First measurement - no baseline for comparison
|
||||
|
||||
**Total Size:** $(numfmt --to=iec-i --suffix=B $current_total)
|
||||
EOF
|
||||
exit 0
|
||||
fi
|
||||
|
||||
baseline_total=$(jq -r '.total' baseline-sizes.json)
|
||||
diff=$((current_total - baseline_total))
|
||||
|
||||
if [[ $baseline_total -gt 0 ]]; then
|
||||
percent=$(awk "BEGIN {printf \"%.2f\", ($diff / $baseline_total) * 100}")
|
||||
else
|
||||
percent=0
|
||||
fi
|
||||
|
||||
echo "size-diff=$diff" >> $GITHUB_OUTPUT
|
||||
echo "size-diff-percent=$percent" >> $GITHUB_OUTPUT
|
||||
|
||||
# Only comment when size is bigger than baseline; optionally require per-image thresholds
|
||||
THRESHOLDS="$SIZE_THRESHOLDS"
|
||||
FAIL_THRESHOLDS="$FAIL_THRESHOLDS"
|
||||
comment_triggered=false
|
||||
fail_triggered=false
|
||||
if [[ $diff -gt 0 ]]; then
|
||||
if [[ -z "$THRESHOLDS" ]] || [[ "$THRESHOLDS" == "{}" ]]; then
|
||||
comment_triggered=true
|
||||
fi
|
||||
fi
|
||||
|
||||
color="gray"
|
||||
if (( $(awk "BEGIN {print ($percent > 0.01)}") )); then
|
||||
color="red"
|
||||
elif (( $(awk "BEGIN {print ($percent < -0.01)}") )); then
|
||||
color="green"
|
||||
fi
|
||||
|
||||
# Generate report
|
||||
if [[ $diff -gt 0 ]]; then
|
||||
emoji="📈"
|
||||
badge=""
|
||||
sign="+"
|
||||
elif [[ $diff -lt 0 ]]; then
|
||||
emoji="📉"
|
||||
badge=""
|
||||
sign="-"
|
||||
else
|
||||
emoji="➡️"
|
||||
badge=""
|
||||
sign=""
|
||||
fi
|
||||
|
||||
cat > report.md << EOF
|
||||
# 📦 Docker Image Size Report
|
||||
|
||||
## $emoji Changes $badge
|
||||
|
||||
| Service | Current | Baseline | Change | Percent |
|
||||
|---------|---------|----------|--------|---------|
|
||||
| **sum of all images** | **$(numfmt --to=iec-i --suffix=B $current_total)** | **$(numfmt --to=iec-i --suffix=B $baseline_total)** | **${sign}$(numfmt --to=iec-i --suffix=B ${diff#-})** | $badge |
|
||||
EOF
|
||||
|
||||
# Get services dynamically from current-sizes.json, sorted by size (largest first)
|
||||
for service in $(jq -r '.services | to_entries | sort_by(-.value) | .[].key' current-sizes.json); do
|
||||
current=$(jq -r ".services.\"$service\"" current-sizes.json)
|
||||
baseline=$(jq -r ".services.\"$service\" // 0" baseline-sizes.json)
|
||||
service_diff=$((current - baseline))
|
||||
|
||||
if [[ $baseline -gt 0 ]]; then
|
||||
service_percent=$(awk "BEGIN {printf \"%.2f\", ($service_diff / $baseline) * 100}")
|
||||
else
|
||||
service_percent=0
|
||||
fi
|
||||
|
||||
# Check per-image thresholds for comment trigger (only when size increased)
|
||||
if [[ $diff -gt 0 ]] && [[ -n "$THRESHOLDS" ]] && [[ "$THRESHOLDS" != "{}" ]]; then
|
||||
threshold_mb=$(echo "$THRESHOLDS" | jq -r ".\"$service\".mb // empty")
|
||||
threshold_pct=$(echo "$THRESHOLDS" | jq -r ".\"$service\".percent // empty")
|
||||
if [[ -n "$threshold_mb" ]] || [[ -n "$threshold_pct" ]]; then
|
||||
exceeded=false
|
||||
if [[ -n "$threshold_mb" ]] && [[ $service_diff -ge $(awk "BEGIN {printf \"%.0f\", $threshold_mb * 1048576}") ]]; then
|
||||
exceeded=true
|
||||
fi
|
||||
if [[ -n "$threshold_pct" ]] && [[ $service_percent != "0.00" ]] && (( $(awk "BEGIN {print ($service_percent >= $threshold_pct)}") )); then
|
||||
exceeded=true
|
||||
fi
|
||||
[[ "$exceeded" == "true" ]] && comment_triggered=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check per-image fail thresholds (task fails when exceeded)
|
||||
if [[ $diff -gt 0 ]] && [[ -n "$FAIL_THRESHOLDS" ]] && [[ "$FAIL_THRESHOLDS" != "{}" ]]; then
|
||||
fail_mb=$(echo "$FAIL_THRESHOLDS" | jq -r ".\"$service\".mb // empty")
|
||||
fail_pct=$(echo "$FAIL_THRESHOLDS" | jq -r ".\"$service\".percent // empty")
|
||||
if [[ -n "$fail_mb" ]] || [[ -n "$fail_pct" ]]; then
|
||||
exceeded=false
|
||||
if [[ -n "$fail_mb" ]] && [[ $service_diff -ge $(awk "BEGIN {printf \"%.0f\", $fail_mb * 1048576}") ]]; then
|
||||
exceeded=true
|
||||
fi
|
||||
if [[ -n "$fail_pct" ]] && [[ $service_percent != "0.00" ]] && (( $(awk "BEGIN {print ($service_percent >= $fail_pct)}") )); then
|
||||
exceeded=true
|
||||
fi
|
||||
[[ "$exceeded" == "true" ]] && fail_triggered=true
|
||||
fi
|
||||
fi
|
||||
|
||||
color="gray"
|
||||
if (( $(awk "BEGIN {print ($service_percent > 0.01)}") )); then
|
||||
color="red"
|
||||
elif (( $(awk "BEGIN {print ($service_percent < -0.01)}") )); then
|
||||
color="green"
|
||||
fi
|
||||
|
||||
if [[ $service_diff -gt 0 ]]; then
|
||||
badge=""
|
||||
sign="+"
|
||||
elif [[ $service_diff -lt 0 ]]; then
|
||||
badge=""
|
||||
sign="-"
|
||||
else
|
||||
badge=""
|
||||
sign=""
|
||||
fi
|
||||
|
||||
echo "| $service | $(numfmt --to=iec-i --suffix=B $current) | $(numfmt --to=iec-i --suffix=B $baseline) | ${sign}$(numfmt --to=iec-i --suffix=B ${service_diff#-}) | $badge |" >> report.md
|
||||
done
|
||||
|
||||
# Generate historical trend chart
|
||||
echo "" >> report.md
|
||||
echo "## 📊 Historical Trend" >> report.md
|
||||
echo "" >> report.md
|
||||
|
||||
# Load history and generate mermaid chart
|
||||
history_count=$(jq 'length' history-data.json)
|
||||
|
||||
if [[ $history_count -gt 0 ]]; then
|
||||
# Get all services from current build
|
||||
all_services=$(jq -r '.services | keys | .[]' current-sizes.json | sort)
|
||||
|
||||
# Generate Mermaid chart data
|
||||
x_labels=""
|
||||
declare -A service_data
|
||||
|
||||
# Initialize service data arrays
|
||||
for service in $all_services; do
|
||||
service_data[$service]=""
|
||||
done
|
||||
|
||||
# Process historical data
|
||||
while IFS= read -r line; do
|
||||
timestamp=$(echo "$line" | jq -r '.timestamp')
|
||||
date_label=$(date -d "$timestamp" +"%m/%d %H:%M")
|
||||
|
||||
if [[ -z "$x_labels" ]]; then
|
||||
x_labels="\"$date_label\""
|
||||
else
|
||||
x_labels="$x_labels, \"$date_label\""
|
||||
fi
|
||||
|
||||
# Add data point for each service
|
||||
for service in $all_services; do
|
||||
size=$(echo "$line" | jq -r ".services.\"$service\" // 0")
|
||||
size_gb=$(awk "BEGIN {printf \"%.2f\", $size / 1073741824}")
|
||||
|
||||
if [[ -z "${service_data[$service]}" ]]; then
|
||||
service_data[$service]="$size_gb"
|
||||
else
|
||||
service_data[$service]="${service_data[$service]}, $size_gb"
|
||||
fi
|
||||
done
|
||||
done < <(jq -c '.[]' history-data.json)
|
||||
|
||||
# Add current PR as last point
|
||||
current_date=$(date -u +"%m/%d %H:%M")
|
||||
x_labels="$x_labels, \"$current_date (PR)\""
|
||||
|
||||
for service in $all_services; do
|
||||
size=$(jq -r ".services.\"$service\" // 0" current-sizes.json)
|
||||
size_gb=$(awk "BEGIN {printf \"%.2f\", $size / 1073741824}")
|
||||
service_data[$service]="${service_data[$service]}, $size_gb"
|
||||
done
|
||||
|
||||
# Generate mermaid chart with multiple lines
|
||||
cat >> report.md << EOF
|
||||
\`\`\`mermaid
|
||||
---
|
||||
config:
|
||||
theme: "dark"
|
||||
xyChart:
|
||||
width: 900
|
||||
height: 400
|
||||
---
|
||||
xychart
|
||||
title "Image Size Evolution by Service (Last 30 Days + This PR)"
|
||||
x-axis [$x_labels]
|
||||
y-axis "Size (GB)" 0 --> 0.5
|
||||
EOF
|
||||
|
||||
# Add a line for each service
|
||||
for service in $all_services; do
|
||||
echo " line \"$service\" [${service_data[$service]}]" >> report.md
|
||||
done
|
||||
|
||||
cat >> report.md << 'EOF'
|
||||
```
|
||||
|
||||
EOF
|
||||
|
||||
# Add summary stats
|
||||
min_size=$(jq '[.[].total] | min' history-data.json)
|
||||
max_size=$(jq '[.[].total] | max' history-data.json)
|
||||
avg_size=$(jq '[.[].total] | add / length' history-data.json)
|
||||
|
||||
cat >> report.md << EOF
|
||||
**Statistics (last $history_count days):**
|
||||
- 📊 Average: $(numfmt --to=iec-i --suffix=B ${avg_size%.*})
|
||||
- ⬇️ Minimum: $(numfmt --to=iec-i --suffix=B $min_size)
|
||||
- ⬆️ Maximum: $(numfmt --to=iec-i --suffix=B $max_size)
|
||||
- 🎯 Current PR: $(numfmt --to=iec-i --suffix=B $current_total)
|
||||
|
||||
EOF
|
||||
|
||||
else
|
||||
cat >> report.md << 'EOF'
|
||||
*No historical data available yet. History tracking starts after merging to develop.*
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
cat >> report.md << EOF
|
||||
|
||||
<details>
|
||||
<summary>ℹ️ About this report</summary>
|
||||
|
||||
This report compares Docker image sizes from this build against the \`$BASELINE_TAG\` baseline.
|
||||
|
||||
- **Tag:** \`$TAG\`
|
||||
- **Baseline:** \`$BASELINE_TAG\`
|
||||
- **Timestamp:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
|
||||
- **Historical data points:** $history_count
|
||||
|
||||
</details>
|
||||
EOF
|
||||
|
||||
echo "comment-triggered=$comment_triggered" >> $GITHUB_OUTPUT
|
||||
echo "failed=$fail_triggered" >> $GITHUB_OUTPUT
|
||||
|
||||
if [[ "$fail_triggered" == "true" ]]; then
|
||||
echo "::error::Docker image size exceeded fail-thresholds (mb/percent). Check the report for details."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Add report to Job Summary
|
||||
if: always()
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ -f report.md ]]; then
|
||||
cat report.md >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
- name: Cleanup worktree
|
||||
if: always()
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ -d /tmp/history-worktree ]]; then
|
||||
git worktree remove /tmp/history-worktree --force 2>/dev/null || true
|
||||
fi
|
||||
|
||||
branding:
|
||||
icon: 'package'
|
||||
color: 'blue'
|
||||
218
.github/actions/meteor-build/action.yml
vendored
Normal file
218
.github/actions/meteor-build/action.yml
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
name: 'Meteor Build'
|
||||
description: 'Build Meteor bundle for production or coverage'
|
||||
|
||||
inputs:
|
||||
type:
|
||||
required: false
|
||||
description: 'production or coverage'
|
||||
default: 'production'
|
||||
reset-meteor:
|
||||
required: false
|
||||
description: 'Reset Meteor'
|
||||
node-version:
|
||||
required: true
|
||||
description: 'Node version'
|
||||
NPM_TOKEN:
|
||||
required: false
|
||||
description: 'NPM token'
|
||||
deno-version:
|
||||
required: true
|
||||
description: 'Deno version'
|
||||
source-hash:
|
||||
required: true
|
||||
description: 'RC cache id (e.g. packages-build-cache-key + meteor apps/meteor archive hash from CI)'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Cache build
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
id: cache-build
|
||||
with:
|
||||
path: /tmp/Rocket.Chat.tar.gz
|
||||
key: ${{ runner.arch }}-${{ runner.os }}-${{ inputs.type }}-rc-build-${{ inputs.source-hash }}
|
||||
|
||||
- name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
with:
|
||||
swap-size-gb: 4
|
||||
|
||||
- name: Merge dependencies for build
|
||||
shell: bash
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
# Merge dependencies and devDependencies into a new 'dependencies' field
|
||||
cd apps/meteor
|
||||
cp package.json package.json.bak
|
||||
jq '.dependencies = (.dependencies + .devDependencies) | del(.devDependencies)' package.json > package.json.tmp && mv package.json.tmp package.json
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
deno-version: ${{ inputs.deno-version }}
|
||||
cache-modules: true
|
||||
install: true
|
||||
type: 'production'
|
||||
NPM_TOKEN: ${{ inputs.NPM_TOKEN }}
|
||||
|
||||
# - name: Free disk space
|
||||
# run: |
|
||||
# sudo apt clean
|
||||
# docker rmi $(docker image ls -aq)
|
||||
# df -h
|
||||
|
||||
- name: Cache vite
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ./node_modules/.vite
|
||||
key: vite-local-cache-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('package.json') }}
|
||||
restore-keys: |
|
||||
vite-local-cache-${{ runner.arch }}-${{ runner.os }}-
|
||||
|
||||
- name: Cache meteor local
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ./apps/meteor/.meteor/local
|
||||
key: meteor-local-cache-${{ runner.arch }}-${{ runner.os }}-${{ inputs.type }}-${{ hashFiles('apps/meteor/.meteor/versions') }}
|
||||
restore-keys: |
|
||||
meteor-local-cache-${{ runner.arch }}-${{ runner.os }}-${{ inputs.type }}-
|
||||
|
||||
- name: Cache meteor
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
with:
|
||||
path: ~/.meteor
|
||||
key: meteor-cache-${{ runner.arch }}-${{ runner.os }}-${{ inputs.type }}-${{ hashFiles('apps/meteor/.meteor/release') }}
|
||||
restore-keys: |
|
||||
meteor-cache-${{ runner.arch }}-${{ runner.os }}-${{ inputs.type }}-
|
||||
|
||||
- name: Install Meteor
|
||||
shell: bash
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
# Restore bin from cache
|
||||
set +e
|
||||
METEOR_SYMLINK_TARGET=$(readlink ~/.meteor/meteor)
|
||||
METEOR_TOOL_DIRECTORY=$(dirname "$METEOR_SYMLINK_TARGET")
|
||||
set -e
|
||||
LAUNCHER=$HOME/.meteor/$METEOR_TOOL_DIRECTORY/scripts/admin/launch-meteor
|
||||
if [ -e $LAUNCHER ]
|
||||
then
|
||||
echo "Cached Meteor bin found, restoring it"
|
||||
sudo cp "$LAUNCHER" "/usr/local/bin/meteor"
|
||||
else
|
||||
echo "No cached Meteor bin found."
|
||||
fi
|
||||
|
||||
# only install meteor if bin isn't found
|
||||
command -v meteor >/dev/null 2>&1 || curl https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh
|
||||
|
||||
- name: Versions
|
||||
shell: bash
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
npm --versions
|
||||
yarn -v
|
||||
node -v
|
||||
meteor --version
|
||||
meteor npm --versions
|
||||
meteor node -v
|
||||
git version
|
||||
|
||||
- uses: rharkor/caching-for-turbo@00a0515f175df9fd2e15c4560144ad5fdbebb0c7 # v2.3.13
|
||||
|
||||
- name: Reset Meteor
|
||||
shell: bash
|
||||
if: ${{ steps.cache-build.outputs.cache-hit != 'true' && inputs.reset-meteor == 'true' }}
|
||||
working-directory: ./apps/meteor
|
||||
run: meteor reset
|
||||
|
||||
- name: Restore packages build
|
||||
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
||||
with:
|
||||
name: packages-build
|
||||
path: /tmp
|
||||
|
||||
- name: Unpack packages build
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xzf /tmp/RocketChat-packages-build.tar.gz -C .
|
||||
|
||||
- name: Build Rocket.Chat
|
||||
shell: bash
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
env:
|
||||
METEOR_PROFILE: 1000
|
||||
BABEL_ENV: ${{ inputs.type }}
|
||||
run: |
|
||||
# check if BABEL_ENV is set to coverage
|
||||
if [[ $BABEL_ENV == "coverage" ]]; then
|
||||
echo -e "rocketchat:coverage\n" >> ./apps/meteor/.meteor/packages
|
||||
# Inject swc-plugin-coverage-instrument into .swcrc for istanbul-compatible coverage
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const swcrc = JSON.parse(fs.readFileSync('./apps/meteor/.swcrc', 'utf8'));
|
||||
swcrc.jsc.experimental = swcrc.jsc.experimental || {};
|
||||
swcrc.jsc.experimental.plugins = swcrc.jsc.experimental.plugins || [];
|
||||
swcrc.jsc.experimental.plugins.push(['swc-plugin-coverage-instrument', {}]);
|
||||
fs.writeFileSync('./apps/meteor/.swcrc', JSON.stringify(swcrc, null, 2) + '\n');
|
||||
"
|
||||
echo "Coverage enabled (SWC istanbul plugin injected)"
|
||||
fi
|
||||
|
||||
# Restore original package.json so meteor should not copy devDependencies
|
||||
mv apps/meteor/package.json.bak apps/meteor/package.json
|
||||
|
||||
yarn build:ci
|
||||
|
||||
declare -a meter_modules_to_remove=(
|
||||
"meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-darwin-arm64" # Removes 35M
|
||||
"meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-linux-x64-musl" # Removes 58M
|
||||
"meteor/babel-compiler/node_modules/@meteorjs/swc-core/.swc/node_modules/@swc/core-linux-arm64-musl" # Removes 44M
|
||||
"meteor/babel-compiler/node_modules/typescript" # Removes 31M
|
||||
# "meteor/babel-compiler/node_modules/@babel" # Removes 14M
|
||||
|
||||
"@rocket.chat/i18n/src" # Removes 16M
|
||||
"typescript" # Removes 19M
|
||||
# "@babel" # Removes 34M - Needed by Minimongo
|
||||
)
|
||||
|
||||
du -s /tmp/dist/bundle
|
||||
|
||||
for dir_path in "${meter_modules_to_remove[@]}"; do
|
||||
path=/tmp/dist/bundle/programs/server/npm/node_modules/${dir_path}
|
||||
|
||||
if [ -d "$path" ]; then
|
||||
rm -rf "$path"
|
||||
|
||||
echo "Removed directory: $path"
|
||||
else
|
||||
echo "Path is not a directory or does not exist: $path"
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove all .d.ts files from node_modules to reduce size
|
||||
# Removes 184M
|
||||
find /tmp/dist/bundle -type f -name "*.d.ts" -delete
|
||||
du -s /tmp/dist/bundle
|
||||
|
||||
- name: Prepare build
|
||||
shell: bash
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
cd /tmp/dist
|
||||
tar czf /tmp/Rocket.Chat.tar.gz bundle
|
||||
|
||||
- name: Store build
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: build-${{ inputs.type }}
|
||||
path: /tmp/Rocket.Chat.tar.gz
|
||||
overwrite: true
|
||||
include-hidden-files: true
|
||||
16
.github/actions/restore-packages/action.yml
vendored
Normal file
16
.github/actions/restore-packages/action.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: 'Restore Packages Build'
|
||||
description: 'Downloads and unpacks the packages build artifact'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Restore packages build
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: packages-build
|
||||
path: /tmp
|
||||
|
||||
- name: Unpack packages build
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xzf /tmp/RocketChat-packages-build.tar.gz -C .
|
||||
120
.github/actions/setup-node/action.yml
vendored
Normal file
120
.github/actions/setup-node/action.yml
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
name: 'Setup Node'
|
||||
description: 'Setup NodeJS'
|
||||
|
||||
inputs:
|
||||
node-version:
|
||||
required: false
|
||||
description: 'Node version. If not provided, read from package.json volta.node'
|
||||
cache-modules:
|
||||
required: false
|
||||
description: 'Cache node_modules'
|
||||
install:
|
||||
required: false
|
||||
description: 'Install dependencies'
|
||||
type:
|
||||
required: false
|
||||
description: 'development or production'
|
||||
default: 'development'
|
||||
deno-version:
|
||||
required: false
|
||||
description: 'Deno version. If not provided, read from .tool-versions'
|
||||
NPM_TOKEN:
|
||||
required: false
|
||||
description: 'NPM token'
|
||||
HARDENED_MODE:
|
||||
required: false
|
||||
description: 'Hardened mode'
|
||||
default: '0'
|
||||
|
||||
outputs:
|
||||
node-version:
|
||||
description: 'Node version'
|
||||
value: ${{ steps.node-version.outputs.node-version }}
|
||||
cache-deno-hit:
|
||||
description: 'Exact key hit for Deno cache'
|
||||
value: ${{ steps.cache-deno.outputs.cache-hit }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
|
||||
steps:
|
||||
- name: Resolve tool versions
|
||||
shell: bash
|
||||
run: |
|
||||
NODE_VERSION="${{ inputs.node-version }}"
|
||||
if [ -z "$NODE_VERSION" ]; then
|
||||
NODE_VERSION=$(node -p "require('./package.json').volta.node")
|
||||
fi
|
||||
echo "NODE_VERSION: ${NODE_VERSION}"
|
||||
echo "NODE_VERSION=${NODE_VERSION}" >> $GITHUB_ENV
|
||||
|
||||
DENO_VERSION="${{ inputs.deno-version }}"
|
||||
if [ -z "$DENO_VERSION" ]; then
|
||||
DENO_VERSION=$(awk '$1=="deno"{ print $2 }' .tool-versions)
|
||||
fi
|
||||
echo "DENO_VERSION: ${DENO_VERSION}"
|
||||
echo "DENO_VERSION=${DENO_VERSION}" >> $GITHUB_ENV
|
||||
|
||||
# Turbo local cache: use rharkor/caching-for-turbo in workflows — not stored here to avoid huge redundant keys.
|
||||
- name: Cache Deno (apps)
|
||||
if: inputs.cache-modules
|
||||
id: cache-deno
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: packages/apps/.deno-cache
|
||||
key: deno-${{ runner.os }}-${{ runner.arch }}-v${{ env.DENO_VERSION }}-${{ hashFiles('packages/apps/deno-runtime/deno.lock') }}
|
||||
restore-keys: |
|
||||
deno-${{ runner.os }}-${{ runner.arch }}-v${{ env.DENO_VERSION }}-
|
||||
|
||||
- name: Use Node.js ${{ env.NODE_VERSION }}
|
||||
id: node-version
|
||||
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
cache: ${{ inputs.cache-modules && 'yarn' || '' }}
|
||||
|
||||
- name: Use Deno ${{ env.DENO_VERSION }}
|
||||
uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4
|
||||
with:
|
||||
deno-version: ${{ env.DENO_VERSION }}
|
||||
|
||||
- name: Cache mongodb-memory-server binary
|
||||
if: inputs.cache-modules
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: ${{ runner.temp }}/mongodb-memory-server
|
||||
key: mongoms-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
- name: Configure mongodb-memory-server cache
|
||||
shell: bash
|
||||
run: |
|
||||
CACHE_DIR="${{ runner.temp }}/mongodb-memory-server"
|
||||
echo "MONGOMS_DOWNLOAD_DIR=$CACHE_DIR" >> $GITHUB_ENV
|
||||
echo "MONGOMS_PREFER_GLOBAL_PATH=false" >> $GITHUB_ENV
|
||||
|
||||
- name: yarn login
|
||||
shell: bash
|
||||
if: inputs.NPM_TOKEN
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=${{ inputs.NPM_TOKEN }}" > ~/.npmrc
|
||||
|
||||
- name: yarn config
|
||||
if: inputs.install
|
||||
shell: bash
|
||||
run: |
|
||||
yarn config set supportedArchitectures --json '{"os": ["linux"], "cpu": ["arm64", "x64"], "libc": ["glibc", "musl"]}'
|
||||
|
||||
- name: yarn install
|
||||
if: inputs.install && inputs.type == 'development'
|
||||
shell: bash
|
||||
run: YARN_ENABLE_HARDENED_MODE=${{ inputs.HARDENED_MODE }} yarn
|
||||
|
||||
- name: yarn install production
|
||||
if: inputs.install && inputs.type == 'production'
|
||||
shell: bash
|
||||
run: YARN_ENABLE_HARDENED_MODE=${{ inputs.HARDENED_MODE }} yarn workspaces focus --all --production
|
||||
|
||||
- name: restore yarn config file
|
||||
if: inputs.install
|
||||
shell: bash
|
||||
run: git checkout -- .yarnrc.yml
|
||||
21
.github/actions/setup-playwright/action.yml
vendored
Normal file
21
.github/actions/setup-playwright/action.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Setup Playwright
|
||||
description: 'Setup Playwright binaries and dependencies'
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
|
||||
steps:
|
||||
- name: Cache Playwright binaries
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
id: cache-playwright
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright
|
||||
# This is the version of Playwright that we are using, if you are willing to upgrade, you should update this.
|
||||
key: playwright-${{ runner.arch }}-${{ runner.os }}-1.52.0
|
||||
|
||||
- name: Install Playwright
|
||||
shell: bash
|
||||
if: steps.cache-playwright.outputs.cache-hit != 'true'
|
||||
working-directory: .
|
||||
run: npx playwright install --with-deps
|
||||
26
.github/actions/update-version-durability/action.yml
vendored
Normal file
26
.github/actions/update-version-durability/action.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Update Version Durability
|
||||
description: Update Version Durability page on Document360
|
||||
|
||||
inputs:
|
||||
LTS_VERSIONS:
|
||||
required: true
|
||||
description: Comma separated list of LTS versions
|
||||
GH_TOKEN:
|
||||
required: true
|
||||
description: GitHub API Token
|
||||
D360_TOKEN:
|
||||
required: true
|
||||
description: Document360 API Token
|
||||
D360_ARTICLE_ID:
|
||||
required: true
|
||||
description: Document360 Article ID
|
||||
D360_USER_ID:
|
||||
required: true
|
||||
description: Document360 User ID used to fork and publish the article
|
||||
PUBLISH:
|
||||
required: true
|
||||
description: Publish Draft
|
||||
|
||||
runs:
|
||||
using: node20
|
||||
main: index.js
|
||||
228
.github/actions/update-version-durability/index.js
vendored
Normal file
228
.github/actions/update-version-durability/index.js
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
import 'colors';
|
||||
import axios from 'axios';
|
||||
import * as Diff from 'diff';
|
||||
import semver from 'semver';
|
||||
import crypto from 'crypto';
|
||||
import fs from 'fs/promises';
|
||||
import BeautyHtml from 'beauty-html';
|
||||
import { DOMParser } from '@xmldom/xmldom';
|
||||
import core from '@actions/core';
|
||||
import { Octokit } from '@octokit/rest';
|
||||
|
||||
const D360_TOKEN = core.getInput('D360_TOKEN');
|
||||
const D360_ARTICLE_ID = core.getInput('D360_ARTICLE_ID');
|
||||
const D360_USER_ID = core.getInput('D360_USER_ID');
|
||||
const PUBLISH = core.getInput('PUBLISH') === 'true';
|
||||
const LTS_VERSIONS = (core.getInput('LTS_VERSIONS') || '7.10').split(',').map((v) => v.trim());
|
||||
|
||||
const octokit = new Octokit({
|
||||
auth: core.getInput('GH_TOKEN'),
|
||||
});
|
||||
|
||||
|
||||
async function requestDocument360(method = 'get', api, data = {}) {
|
||||
return axios.request({
|
||||
method,
|
||||
maxBodyLength: Infinity,
|
||||
url: `https://apihub.us.document360.io/v1/${api}`,
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'api_token': D360_TOKEN,
|
||||
},
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
function md5(text) {
|
||||
return crypto.createHash('md5').update(text).digest("hex");
|
||||
}
|
||||
|
||||
async function generateTable({ owner, repo } = {}) {
|
||||
const response = await requestDocument360('get', `Articles/${D360_ARTICLE_ID}/en`);
|
||||
|
||||
// console.log(response.data.data);
|
||||
|
||||
// const releasesResult = JSON.parse(await fs.readFile('/tmp/releasesResult'));
|
||||
const releasesResult = await octokit.paginate(octokit.repos.listReleases.endpoint.merge({ owner, repo, per_page: 100 }));
|
||||
// await fs.writeFile('/tmp/releasesResult', JSON.stringify(releasesResult));
|
||||
|
||||
const releases = releasesResult
|
||||
.filter((release) => !release.tag_name.includes('-rc') && semver.gte(release.tag_name, '1.0.0'))
|
||||
.sort((a, b) => semver.compare(b.tag_name, a.tag_name));
|
||||
|
||||
const releasesMap = {};
|
||||
|
||||
for (const release of releases) {
|
||||
release.releaseDate = new Date(release.published_at);
|
||||
|
||||
releasesMap[release.tag_name] = release;
|
||||
}
|
||||
|
||||
let index = 0;
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const release = releases[index];
|
||||
|
||||
release.minor_tag = release.tag_name.replace(/\.\d+$/, '');
|
||||
release.minorRelease = releasesMap[`${release.minor_tag}.0`];
|
||||
|
||||
if (!releases[index + 1]) {
|
||||
break;
|
||||
}
|
||||
|
||||
const currentVersion = semver.parse(release.tag_name);
|
||||
const previousVersion = semver.parse(releases[index + 1].tag_name);
|
||||
|
||||
releases[index + 1].nextRelease = release;
|
||||
|
||||
// Remove duplicated due to patches
|
||||
if (currentVersion.major === previousVersion.major && currentVersion.minor === previousVersion.minor) {
|
||||
releases.splice(index + 1, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Mark LTS
|
||||
if (LTS_VERSIONS.includes(`${currentVersion.major}.${currentVersion.minor}`)) {
|
||||
release.lts = true;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
releases[0].last = true;
|
||||
|
||||
const releaseData = [];
|
||||
|
||||
for (const { tag_name, html_url, lts, last, nextRelease, minorRelease, minor_tag} of releases) {
|
||||
let supportDate;
|
||||
let supportDateStart;
|
||||
|
||||
let releasedAt = new Date(minorRelease.releaseDate);
|
||||
releasedAt.setDate(1);
|
||||
|
||||
let minorDate = new Date(minorRelease.releaseDate);
|
||||
minorDate.setDate(1);
|
||||
supportDateStart = minorDate;
|
||||
supportDate = new Date(minorDate);
|
||||
supportDate.setMonth(supportDate.getMonth() + (lts ? 12 : 6));
|
||||
|
||||
releaseData.push({
|
||||
release: {
|
||||
version: minor_tag,
|
||||
releasedAt,
|
||||
extendedSupport: {
|
||||
start: supportDateStart,
|
||||
end: supportDate,
|
||||
},
|
||||
lts: lts === true,
|
||||
},
|
||||
latestPatch: {
|
||||
version: tag_name,
|
||||
url: html_url,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function header({data, salt = ''}) {
|
||||
return [
|
||||
'<th colspan="1" data-vertical-align="middle" data-horizontal-align="left" rowspan="1" style="vertical-align:middle;text-align:left;">',
|
||||
`<p data-block-id="${md5(salt+data)}">${data}</p>`,
|
||||
'</th>',
|
||||
].join('');
|
||||
}
|
||||
|
||||
function line({data, salt = ''}) {
|
||||
return [
|
||||
'<td colspan="1" rowspan="1" data-vertical-align="middle" data-horizontal-align="left" style="vertical-align:middle;text-align:left;">',
|
||||
`<p data-block-id="${md5(salt+data)}">${data}</p>`,
|
||||
'</td>',
|
||||
].join('');
|
||||
}
|
||||
|
||||
const text = [
|
||||
'<tr>',
|
||||
header({data: 'Rocket.Chat Release'}),
|
||||
header({data: 'Released At'}),
|
||||
header({data: 'End of Life'}),
|
||||
'</tr>',
|
||||
];
|
||||
|
||||
releaseData.forEach(({release, latestPatch}) => {
|
||||
const releasedAt = release.releasedAt.toLocaleString('en', { month: 'short', year: "numeric" });
|
||||
const endOfLife = !release.extendedSupport
|
||||
? 'TBD'
|
||||
: release.extendedSupport.end.toLocaleString('en', { month: 'short', year: "numeric" });
|
||||
const link = `${release.version}${release.lts ? " LTS" : ""} (<a href="${latestPatch.url}" target="_blank" translate="no">${latestPatch.version}</a>)`;
|
||||
|
||||
text.push(
|
||||
'<tr>',
|
||||
line({data: link}),
|
||||
line({data: releasedAt, salt: release.version}),
|
||||
line({data: endOfLife, salt: release.version}),
|
||||
'</tr>',
|
||||
);
|
||||
});
|
||||
|
||||
const content = response.data.data.html_content.replace(/<tbody>.+(\n.+)*<\/tbody>/m, `<tbody>${text.join('').replace(/\t|\n/g, '')}</tbody>`)
|
||||
|
||||
// console.log(content);
|
||||
|
||||
const parser = new BeautyHtml({ parser: DOMParser });
|
||||
const diff = Diff.diffLines(parser.beautify(response.data.data.html_content), parser.beautify(content), { ignoreWhitespace: true, newlineIsToken: false });
|
||||
diff.forEach((item) => {
|
||||
let color = 'green';
|
||||
|
||||
if (item.removed) {
|
||||
color = 'red';
|
||||
}
|
||||
|
||||
if (item.removed || item.added) {
|
||||
item.value.split('\n').forEach((line) => {
|
||||
if (line === '') { return };
|
||||
console.log(`${item.removed ? '-' : '+'} ${line}`[color]);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
if (diff.length === 1) {
|
||||
console.log('No changes found');
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.data.data.status === 3) {
|
||||
console.log('forking article', response.data.data.version_number);
|
||||
|
||||
const forkResponse = await requestDocument360('put', `Articles/${D360_ARTICLE_ID}/fork`, {
|
||||
lang_code: "en",
|
||||
user_id: D360_USER_ID,
|
||||
version_number: response.data.data.version_number,
|
||||
});
|
||||
|
||||
console.log(forkResponse.data);
|
||||
|
||||
if (!forkResponse.data.success) {
|
||||
throw new Error(`Failed to fork article: ${JSON.stringify(forkResponse.data.errors)}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Updating article');
|
||||
const updateResponse = await requestDocument360('put', `Articles/${D360_ARTICLE_ID}/en`, {
|
||||
content,
|
||||
});
|
||||
|
||||
console.log(updateResponse.data);
|
||||
|
||||
if (PUBLISH) {
|
||||
console.log('publishing article', updateResponse.data.data.version_number);
|
||||
|
||||
const forkResponse = await requestDocument360('post', `Articles/${D360_ARTICLE_ID}/en/publish`, {
|
||||
user_id: D360_USER_ID,
|
||||
version_number: updateResponse.data.data.version_number,
|
||||
publish_message: 'Update support versions table via GitHub Action',
|
||||
});
|
||||
|
||||
console.log(forkResponse.data);
|
||||
}
|
||||
}
|
||||
|
||||
generateTable({ owner: 'RocketChat', repo: 'Rocket.Chat' });
|
||||
717
.github/actions/update-version-durability/package-lock.json
generated
vendored
Normal file
717
.github/actions/update-version-durability/package-lock.json
generated
vendored
Normal file
@@ -0,0 +1,717 @@
|
||||
{
|
||||
"name": "scripts",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "scripts",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@octokit/rest": "^21.0.2",
|
||||
"@xmldom/xmldom": "^0.8.15",
|
||||
"axios": "^1.18.1",
|
||||
"beauty-html": "^1.3.1",
|
||||
"colors": "^1.4.0",
|
||||
"diff": "^5.1.0",
|
||||
"semver": "^7.5.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz",
|
||||
"integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/http-client": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/exec": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/io": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.1.tgz",
|
||||
"integrity": "sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6",
|
||||
"undici": "^5.25.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/io": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz",
|
||||
"integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.1.tgz",
|
||||
"integrity": "sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "6.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.6.tgz",
|
||||
"integrity": "sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^5.0.0",
|
||||
"@octokit/graphql": "^8.2.2",
|
||||
"@octokit/request": "^9.2.3",
|
||||
"@octokit/request-error": "^6.1.8",
|
||||
"@octokit/types": "^14.0.0",
|
||||
"before-after-hook": "^3.0.2",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
|
||||
"version": "25.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
|
||||
"integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/core/node_modules/@octokit/types": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
|
||||
"integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^25.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "10.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.4.tgz",
|
||||
"integrity": "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^14.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
|
||||
"version": "25.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
|
||||
"integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
|
||||
"integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^25.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.2.tgz",
|
||||
"integrity": "sha512-Yi8hcoqsrXGdt0yObxbebHXFOiUA+2v3n53epuOg1QUgOB6c4XzvisBNVXJSl8RYA5KrDuSL2yq9Qmqe5N0ryA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^9.2.3",
|
||||
"@octokit/types": "^14.0.0",
|
||||
"universal-user-agent": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
|
||||
"version": "25.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
|
||||
"integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
|
||||
"integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^25.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "23.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
|
||||
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "11.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
|
||||
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-request-log": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
|
||||
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "13.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.5.0.tgz",
|
||||
"integrity": "sha512-9Pas60Iv9ejO3WlAX3maE1+38c5nqbJXV5GrncEfkndIpZrJ/WPMRd2xYDcPPEt5yzpxcjw9fWNoPhsSGzqKqw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
|
||||
"version": "24.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-24.2.0.tgz",
|
||||
"integrity": "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
|
||||
"version": "13.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.10.0.tgz",
|
||||
"integrity": "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^24.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "9.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.4.tgz",
|
||||
"integrity": "sha512-q8ybdytBmxa6KogWlNa818r0k1wlqzNC+yNkcQDECHvQo8Vmstrg18JwqJHdJdUiHD2sjlwBgSm9kHkOKe2iyA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^10.1.4",
|
||||
"@octokit/request-error": "^6.1.8",
|
||||
"@octokit/types": "^14.0.0",
|
||||
"fast-content-type-parse": "^2.0.0",
|
||||
"universal-user-agent": "^7.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.8.tgz",
|
||||
"integrity": "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^14.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
|
||||
"version": "25.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
|
||||
"integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
|
||||
"integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^25.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
|
||||
"version": "25.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-25.1.0.tgz",
|
||||
"integrity": "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/request/node_modules/@octokit/types": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-14.1.0.tgz",
|
||||
"integrity": "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^25.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
|
||||
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^6.1.4",
|
||||
"@octokit/plugin-paginate-rest": "^11.4.2",
|
||||
"@octokit/plugin-request-log": "^5.3.1",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
|
||||
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^23.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.8.15",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.15.tgz",
|
||||
"integrity": "sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.18.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz",
|
||||
"integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.16.0",
|
||||
"form-data": "^4.0.5",
|
||||
"https-proxy-agent": "^5.0.1",
|
||||
"proxy-from-env": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/beauty-html": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/beauty-html/-/beauty-html-1.3.1.tgz",
|
||||
"integrity": "sha512-c0iKWc527T2MQcYhIMMw9OHN8kcXSf/ijadWzURhZWi6e6cnBXxAQ5IlXbYd0YZJE9lFtXRB1fJVQrvJf5DmPQ=="
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
|
||||
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/colors": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
|
||||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"engines": {
|
||||
"node": ">=0.1.90"
|
||||
}
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz",
|
||||
"integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-content-type-parse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
|
||||
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fastify"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fastify"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz",
|
||||
"integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz",
|
||||
"integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.4",
|
||||
"mime-types": "^2.1.35"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
||||
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
|
||||
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.28.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz",
|
||||
"integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz",
|
||||
"integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
24
.github/actions/update-version-durability/package.json
vendored
Normal file
24
.github/actions/update-version-durability/package.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "scripts",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@octokit/rest": "^21.0.2",
|
||||
"axios": "^1.18.1",
|
||||
"beauty-html": "^1.3.1",
|
||||
"colors": "^1.4.0",
|
||||
"diff": "^5.1.0",
|
||||
"semver": "^7.5.4",
|
||||
"@xmldom/xmldom": "^0.8.15"
|
||||
},
|
||||
"overrides": {
|
||||
"undici": "6.28.0"
|
||||
}
|
||||
}
|
||||
212
.github/agents/bug-resolution-agent.md
vendored
Normal file
212
.github/agents/bug-resolution-agent.md
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
---
|
||||
name: Bug Resolution Agent
|
||||
description: |
|
||||
A focused agent that resolves GitHub issues by applying minimal, test-driven fixes.
|
||||
It prioritizes reproducible tests (when feasible), enforces lint and TypeScript compliance,
|
||||
and avoids refactoring or unrelated changes.
|
||||
---
|
||||
|
||||
# Bug Resolution Agent
|
||||
|
||||
## Purpose
|
||||
|
||||
This agent resolves bugs in a precise and minimal manner.
|
||||
Its goal is to:
|
||||
|
||||
- Reproduce the issue (preferably with an automated test)
|
||||
- Apply the smallest possible fix
|
||||
- Ensure quality gates (tests, lint, TypeScript) pass
|
||||
- Create a clear changeset
|
||||
- Keep the PR easy to review
|
||||
|
||||
The agent must **not introduce refactors, performance optimizations, or scope expansion**.
|
||||
|
||||
---
|
||||
|
||||
## Operating Principles
|
||||
|
||||
1. **Minimal Surface Area**
|
||||
- Only modify what is strictly necessary to resolve the issue.
|
||||
- Do not refactor unrelated code.
|
||||
- Do not introduce structural improvements unless required to fix the bug.
|
||||
|
||||
2. **Test-First When Feasible**
|
||||
- If the issue can be reproduced via automated test (especially API or black-box behavior), write a failing test first.
|
||||
- The test must fail before the fix and pass after the fix.
|
||||
|
||||
3. **Quality Gates Are Mandatory**
|
||||
- All existing tests must pass.
|
||||
- Lint must pass with no new warnings or errors.
|
||||
- TypeScript type checking must pass without errors.
|
||||
- Build must succeed.
|
||||
|
||||
4. **Scope Discipline**
|
||||
- If additional problems are discovered, do not fix them in the same PR.
|
||||
- Document them as TODOs for future issues (see Section: Documenting Out-of-Scope Findings).
|
||||
|
||||
---
|
||||
|
||||
## Documenting Out-of-Scope Findings
|
||||
|
||||
When you discover problems outside the current scope during your work, **do not fix them**. Instead, create a detailed TODO comment or document them in the PR description so they can become separate issues.
|
||||
|
||||
### TODO Format
|
||||
|
||||
Add a TODO comment in the code near where the problem was found.
|
||||
|
||||
**Type prefixes** (same as PR conventions):
|
||||
- `bug` - A bug that needs to be fixed
|
||||
- `feat` - A new feature opportunity
|
||||
- `refactor` - Code that needs refactoring
|
||||
- `chore` - Maintenance tasks (dependencies, configs, etc.)
|
||||
- `test` - Missing or incomplete tests
|
||||
|
||||
**Optional labels** (GitHub labels in brackets):
|
||||
- `[security]` - Security-related issues
|
||||
- `[performance]` - Performance improvements
|
||||
- `[a11y]` - Accessibility issues
|
||||
- `[i18n]` - Internationalization issues
|
||||
- `[breaking]` - Breaking changes
|
||||
- Any other GitHub label relevant to the issue
|
||||
|
||||
```typescript
|
||||
// TODO: type [optional-label] <Brief title>
|
||||
// Problem: <Detailed description of what is wrong>
|
||||
// Location: <File path and function/component name>
|
||||
// Impact: <How this affects the system - severity, affected features>
|
||||
// Suggested fix: <High-level approach to resolve>
|
||||
// Discovered while: <Reference to current PR/issue>
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
// TODO: bug [high-priority] Race condition in message delivery
|
||||
// Problem: When multiple messages are sent rapidly, the order is not guaranteed
|
||||
// due to async handling without proper sequencing.
|
||||
// Location: apps/meteor/server/services/messages/sendMessage.ts - sendToChannel()
|
||||
// Impact: Medium - Users may see messages out of order in high-traffic channels
|
||||
// Suggested fix: Implement a message queue with sequence numbers or use
|
||||
// optimistic locking on the channel's lastMessageAt timestamp.
|
||||
// Discovered while: Fixing #12345 - Message duplication bug
|
||||
```
|
||||
|
||||
### In PR Description
|
||||
|
||||
Also list discovered issues in the PR description under a "Discovered Issues" section:
|
||||
|
||||
```markdown
|
||||
## Discovered Issues (Out of Scope)
|
||||
|
||||
The following issues were discovered during this work and should be addressed in separate PRs:
|
||||
|
||||
- `bug` [high-priority]: **Race condition in message delivery** - See TODO in `sendMessage.ts:142`
|
||||
- `test`: **Missing input validation tests** - See TODO in `userController.ts:87`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Execution Flow
|
||||
|
||||
### 1. Analyze the Issue
|
||||
|
||||
- Carefully read the issue description.
|
||||
- Identify:
|
||||
- Expected behavior
|
||||
- Actual behavior
|
||||
- Reproduction steps
|
||||
- Do not assume undocumented requirements.
|
||||
|
||||
---
|
||||
|
||||
### 2. Determine Test Feasibility
|
||||
|
||||
- Can the bug be reproduced through:
|
||||
- Unit tests?
|
||||
- Integration tests?
|
||||
- API black-box tests?
|
||||
|
||||
If **yes** → proceed to Step 3.
|
||||
If **no** → proceed directly to Step 4.
|
||||
|
||||
---
|
||||
|
||||
### 3. Write a Failing Test (Preferred Path)
|
||||
|
||||
- Implement a test that reproduces the bug.
|
||||
- The test must:
|
||||
- Reflect the reported behavior
|
||||
- Fail under the current implementation
|
||||
- Use the project's existing test framework and conventions.
|
||||
- Avoid introducing new testing patterns unless strictly required.
|
||||
|
||||
---
|
||||
|
||||
### 4. Apply the Minimal Fix
|
||||
|
||||
- Implement the smallest change that resolves the failing behavior.
|
||||
- Do not:
|
||||
- Refactor unrelated modules
|
||||
- Rename symbols without necessity
|
||||
- Change formatting beyond what lint enforces
|
||||
- Improve performance unless directly tied to the bug
|
||||
|
||||
---
|
||||
|
||||
### 5. Validate the Fix
|
||||
|
||||
Ensure:
|
||||
|
||||
- The newly created test passes.
|
||||
- All existing tests pass.
|
||||
- Lint passes.
|
||||
- TypeScript compilation passes.
|
||||
- Build succeeds.
|
||||
|
||||
If any of these fail, adjust only what is required to restore compliance.
|
||||
|
||||
---
|
||||
|
||||
### 6. Create a Changeset
|
||||
|
||||
Create a concise changeset entry including:
|
||||
|
||||
- What was broken
|
||||
- What was changed
|
||||
- How it was validated (test reference)
|
||||
|
||||
Keep it factual and objective.
|
||||
|
||||
---
|
||||
|
||||
### 7. Open the Pull Request
|
||||
|
||||
The PR must:
|
||||
|
||||
- Clearly reference the original issue.
|
||||
- Highlight the test added (if applicable).
|
||||
- Describe the minimal fix applied.
|
||||
- Avoid mentioning improvements outside the issue scope.
|
||||
|
||||
---
|
||||
|
||||
## Non-Goals
|
||||
|
||||
This agent must NOT:
|
||||
|
||||
- Perform refactoring
|
||||
- Improve unrelated code quality
|
||||
- Introduce stylistic changes
|
||||
- Expand scope beyond the issue
|
||||
- Combine multiple bug fixes in one PR
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
A successful run results in:
|
||||
|
||||
- A minimal diff
|
||||
- A reproducible test (when feasible)
|
||||
- Passing CI (tests, lint, TypeScript)
|
||||
- A clear and review-friendly Pull Request
|
||||
335
.github/agents/feature-development-agent.md
vendored
Normal file
335
.github/agents/feature-development-agent.md
vendored
Normal file
@@ -0,0 +1,335 @@
|
||||
---
|
||||
name: Feature Development Agent
|
||||
description: |
|
||||
A comprehensive agent that implements new features following best practices,
|
||||
with proper planning, testing, documentation, and incremental delivery.
|
||||
It ensures features are well-designed, tested, and maintainable.
|
||||
---
|
||||
|
||||
# Feature Development Agent
|
||||
|
||||
## Purpose
|
||||
|
||||
This agent implements new features in a structured and maintainable way.
|
||||
Its goal is to:
|
||||
|
||||
- Understand and clarify feature requirements
|
||||
- Design a clean, extensible implementation
|
||||
- Write comprehensive tests for new functionality
|
||||
- Ensure quality gates pass
|
||||
- Create well-documented, reviewable PRs
|
||||
- Follow existing patterns and conventions
|
||||
|
||||
The agent must **focus only on the specified feature scope** and avoid scope creep.
|
||||
|
||||
---
|
||||
|
||||
## Operating Principles
|
||||
|
||||
1. **Requirements First**
|
||||
- Fully understand the feature before writing code.
|
||||
- Clarify ambiguities before implementation.
|
||||
- Define acceptance criteria upfront.
|
||||
|
||||
2. **Design Before Code**
|
||||
- Plan the architecture and approach.
|
||||
- Consider edge cases and error handling.
|
||||
- Identify integration points with existing code.
|
||||
|
||||
3. **Test-Driven Development**
|
||||
- Write tests that define expected behavior.
|
||||
- Tests should cover happy paths and edge cases.
|
||||
- Tests serve as living documentation.
|
||||
|
||||
4. **Quality Gates Are Mandatory**
|
||||
- All tests (new and existing) must pass.
|
||||
- Lint must pass with no new warnings or errors.
|
||||
- TypeScript type checking must pass without errors.
|
||||
- Build must succeed.
|
||||
|
||||
5. **Incremental Delivery**
|
||||
- Break features into deliverable increments.
|
||||
- Each increment should be functional and valuable.
|
||||
- Prefer feature flags for large features.
|
||||
|
||||
6. **Consistency**
|
||||
- Follow existing code patterns and conventions.
|
||||
- Maintain consistency with the codebase style.
|
||||
- Reuse existing utilities and components.
|
||||
|
||||
7. **Scope Discipline**
|
||||
- Focus only on the specified feature requirements.
|
||||
- Do not fix unrelated bugs discovered during implementation.
|
||||
- Do not refactor existing code beyond what's needed for the feature.
|
||||
- Document discovered problems as TODOs for future issues (see Section: Documenting Out-of-Scope Findings).
|
||||
|
||||
---
|
||||
|
||||
## Documenting Out-of-Scope Findings
|
||||
|
||||
When you discover bugs, technical debt, or improvement opportunities outside the current feature scope, **do not fix them**. Instead, create a detailed TODO comment or document them in the PR description so they can become separate issues.
|
||||
|
||||
### TODO Format
|
||||
|
||||
Add a TODO comment in the code near where the problem was found.
|
||||
|
||||
**Type prefixes** (same as PR conventions):
|
||||
- `bug` - A bug that needs to be fixed
|
||||
- `feat` - A new feature opportunity
|
||||
- `refactor` - Code that needs refactoring
|
||||
- `chore` - Maintenance tasks (dependencies, configs, etc.)
|
||||
- `test` - Missing or incomplete tests
|
||||
|
||||
**Optional labels** (GitHub labels in brackets):
|
||||
- `[security]` - Security-related issues
|
||||
- `[performance]` - Performance improvements
|
||||
- `[a11y]` - Accessibility issues
|
||||
- `[i18n]` - Internationalization issues
|
||||
- `[breaking]` - Breaking changes
|
||||
- Any other GitHub label relevant to the issue
|
||||
|
||||
```typescript
|
||||
// TODO: type [optional-label] <Brief title>
|
||||
// Problem: <Detailed description of what is wrong>
|
||||
// Location: <File path and function/component name>
|
||||
// Impact: <How this affects the system - severity, affected features>
|
||||
// Suggested fix: <High-level approach to resolve>
|
||||
// Discovered while: <Reference to current PR/issue>
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
// TODO: bug [security] Missing rate limiting on user search endpoint
|
||||
// Problem: The /api/v1/users.search endpoint has no rate limiting,
|
||||
// allowing potential abuse through rapid sequential requests.
|
||||
// Location: apps/meteor/app/api/server/v1/users.ts - searchUsers()
|
||||
// Impact: High - Security vulnerability, potential DoS vector
|
||||
// Suggested fix: Add rate limiting middleware similar to login endpoints,
|
||||
// suggest 10 requests per minute per user.
|
||||
// Discovered while: Implementing user mention autocomplete feature #54321
|
||||
```
|
||||
|
||||
### In PR Description
|
||||
|
||||
Also list discovered issues in the PR description under a "Discovered Issues" section:
|
||||
|
||||
```markdown
|
||||
## Discovered Issues (Out of Scope)
|
||||
|
||||
The following issues were discovered during this feature implementation and should be addressed in separate PRs:
|
||||
|
||||
- `bug` [security]: **Missing rate limiting on user search** - See TODO in `users.ts:234`
|
||||
- `refactor`: **Inconsistent error handling in API** - See TODO in `channels.ts:156`
|
||||
- `chore`: **Outdated TypeScript types** - See TODO in `types/user.d.ts:12`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Execution Flow
|
||||
|
||||
### 1. Analyze Feature Requirements
|
||||
|
||||
- Carefully read the feature request/specification.
|
||||
- Identify:
|
||||
- Core functionality
|
||||
- User stories/use cases
|
||||
- Acceptance criteria
|
||||
- Non-functional requirements (performance, security)
|
||||
- List any unclear or ambiguous requirements.
|
||||
- Do not assume undocumented behavior.
|
||||
|
||||
---
|
||||
|
||||
### 2. Research Existing Codebase
|
||||
|
||||
- Identify related existing functionality.
|
||||
- Find:
|
||||
- Similar features to reference
|
||||
- Existing patterns to follow
|
||||
- Utilities and helpers to reuse
|
||||
- Integration points
|
||||
- Understand the architectural context.
|
||||
|
||||
---
|
||||
|
||||
### 3. Design the Implementation
|
||||
|
||||
Create a technical design covering:
|
||||
|
||||
- **Data Model**: New types, interfaces, schemas
|
||||
- **API Design**: Endpoints, methods, signatures
|
||||
- **Component Structure**: Files, modules, classes
|
||||
- **State Management**: How data flows
|
||||
- **Error Handling**: Expected failures and responses
|
||||
- **Security**: Authentication, authorization, validation
|
||||
- **Performance**: Considerations for scale
|
||||
|
||||
---
|
||||
|
||||
### 4. Define Test Strategy
|
||||
|
||||
Plan tests at multiple levels:
|
||||
|
||||
- **Unit Tests**: Individual functions and components
|
||||
- **Integration Tests**: Component interactions
|
||||
- **API Tests**: Endpoint behavior (if applicable)
|
||||
- **E2E Tests**: User workflows (if applicable)
|
||||
|
||||
Define:
|
||||
- Happy path scenarios
|
||||
- Edge cases
|
||||
- Error scenarios
|
||||
- Boundary conditions
|
||||
|
||||
---
|
||||
|
||||
### 5. Implement Incrementally
|
||||
|
||||
For each implementation increment:
|
||||
|
||||
#### 5.1 Write Tests First
|
||||
- Define expected behavior through tests.
|
||||
- Tests should initially fail (TDD red phase).
|
||||
|
||||
#### 5.2 Implement the Code
|
||||
- Write the minimum code to pass tests.
|
||||
- Follow existing patterns and conventions.
|
||||
- Add proper TypeScript types.
|
||||
- Include error handling.
|
||||
|
||||
#### 5.3 Refactor if Needed
|
||||
- Clean up the implementation.
|
||||
- Ensure code quality standards are met.
|
||||
- Keep tests passing.
|
||||
|
||||
#### 5.4 Verify Quality Gates
|
||||
- Run all tests.
|
||||
- Run lint.
|
||||
- Run TypeScript compilation.
|
||||
- Build the project.
|
||||
|
||||
---
|
||||
|
||||
### 6. Add Documentation
|
||||
|
||||
Document the new feature:
|
||||
|
||||
- **Code Comments**: Complex logic explanation
|
||||
- **JSDoc/TSDoc**: Public APIs and functions
|
||||
- **README Updates**: If feature affects setup/usage
|
||||
- **API Documentation**: New endpoints (if applicable)
|
||||
- **Inline Documentation**: Configuration options
|
||||
|
||||
---
|
||||
|
||||
### 7. Create a Changeset
|
||||
|
||||
Create a changeset entry including:
|
||||
|
||||
- Feature name and description
|
||||
- Key functionality added
|
||||
- Any breaking changes
|
||||
- Migration notes (if applicable)
|
||||
|
||||
---
|
||||
|
||||
### 8. Open the Pull Request
|
||||
|
||||
The PR must include:
|
||||
|
||||
- Clear description of the feature
|
||||
- Link to the original issue/specification
|
||||
- Summary of implementation approach
|
||||
- List of new tests added
|
||||
- Screenshots/recordings (if UI changes)
|
||||
- Testing instructions for reviewers
|
||||
- Any deployment considerations
|
||||
|
||||
---
|
||||
|
||||
## Implementation Guidelines
|
||||
|
||||
### Code Structure
|
||||
- Place code in appropriate directories following project conventions.
|
||||
- Create new files for distinct functionality.
|
||||
- Keep files focused and reasonably sized.
|
||||
|
||||
### Type Safety
|
||||
- Define explicit types for all new code.
|
||||
- Avoid `any` types.
|
||||
- Use generics where appropriate.
|
||||
- Export types that consumers need.
|
||||
|
||||
### Error Handling
|
||||
- Handle all expected error cases.
|
||||
- Provide meaningful error messages.
|
||||
- Use appropriate error types/codes.
|
||||
- Log errors appropriately.
|
||||
|
||||
### Security
|
||||
- Validate all inputs.
|
||||
- Sanitize outputs where needed.
|
||||
- Follow authentication/authorization patterns.
|
||||
- Never expose sensitive data.
|
||||
|
||||
### Performance
|
||||
- Consider performance implications.
|
||||
- Avoid unnecessary computations.
|
||||
- Use appropriate data structures.
|
||||
- Add caching where beneficial.
|
||||
|
||||
---
|
||||
|
||||
## Feature Categories
|
||||
|
||||
### API Features
|
||||
- Define clear endpoint contracts.
|
||||
- Follow REST/GraphQL conventions.
|
||||
- Include proper validation.
|
||||
- Document request/response schemas.
|
||||
|
||||
### UI Features
|
||||
- Follow design system patterns.
|
||||
- Ensure accessibility (a11y).
|
||||
- Support internationalization (i18n).
|
||||
- Handle loading and error states.
|
||||
|
||||
### Backend Features
|
||||
- Design for scalability.
|
||||
- Consider data migration needs.
|
||||
- Handle edge cases gracefully.
|
||||
- Add appropriate logging.
|
||||
|
||||
### Integration Features
|
||||
- Define clear interfaces.
|
||||
- Handle external service failures.
|
||||
- Add retry logic where appropriate.
|
||||
- Document integration requirements.
|
||||
|
||||
---
|
||||
|
||||
## Non-Goals
|
||||
|
||||
This agent must NOT:
|
||||
|
||||
- Implement features beyond the defined scope
|
||||
- Fix unrelated bugs (create separate issues)
|
||||
- Refactor existing code unrelated to the feature
|
||||
- Skip test coverage
|
||||
- Ignore existing patterns and conventions
|
||||
- Make breaking changes without explicit approval
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
A successful feature implementation results in:
|
||||
|
||||
- Fully functional feature matching requirements
|
||||
- Comprehensive test coverage
|
||||
- Passing CI (tests, lint, TypeScript)
|
||||
- Clear documentation
|
||||
- Easy-to-review Pull Request
|
||||
- No regressions in existing functionality
|
||||
- Ready for production deployment
|
||||
261
.github/agents/refactor-agent.md
vendored
Normal file
261
.github/agents/refactor-agent.md
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
---
|
||||
name: Refactor Agent
|
||||
description: |
|
||||
A disciplined agent that performs code refactoring with a focus on improving code quality,
|
||||
maintainability, and readability without changing external behavior. It ensures all tests
|
||||
pass before and after changes, and creates incremental, reviewable PRs.
|
||||
---
|
||||
|
||||
# Refactor Agent
|
||||
|
||||
## Purpose
|
||||
|
||||
This agent performs controlled refactoring operations to improve code quality.
|
||||
Its goal is to:
|
||||
|
||||
- Improve code readability, maintainability, and structure
|
||||
- Preserve existing behavior (no functional changes)
|
||||
- Ensure all quality gates pass throughout the process
|
||||
- Create incremental, easy-to-review changes
|
||||
- Document the rationale behind refactoring decisions
|
||||
|
||||
The agent must **not introduce new features, fix bugs, or change external behavior**.
|
||||
|
||||
---
|
||||
|
||||
## Operating Principles
|
||||
|
||||
1. **Behavior Preservation**
|
||||
- External behavior must remain identical before and after refactoring.
|
||||
- All existing tests must continue to pass.
|
||||
- If tests fail, the refactoring approach must be reconsidered.
|
||||
|
||||
2. **Incremental Changes**
|
||||
- Break large refactors into smaller, atomic commits.
|
||||
- Each commit should be independently valid and reviewable.
|
||||
- Prefer multiple small PRs over one large PR when appropriate.
|
||||
|
||||
3. **Quality Gates Are Mandatory**
|
||||
- All existing tests must pass.
|
||||
- Lint must pass with no new warnings or errors.
|
||||
- TypeScript type checking must pass without errors.
|
||||
- Build must succeed.
|
||||
|
||||
4. **Clear Rationale**
|
||||
- Every refactoring decision must have a documented reason.
|
||||
- Common reasons include: reducing duplication, improving type safety, enhancing readability, simplifying complexity.
|
||||
|
||||
5. **Scope Discipline**
|
||||
- Stay focused on the refactoring goal.
|
||||
- Do not fix unrelated bugs discovered during refactoring.
|
||||
- Do not add new features or optimizations.
|
||||
- Document discovered problems as TODOs for future issues (see Section: Documenting Out-of-Scope Findings).
|
||||
|
||||
---
|
||||
|
||||
## Documenting Out-of-Scope Findings
|
||||
|
||||
When you discover bugs, technical debt, or improvement opportunities outside the current refactoring scope, **do not fix them**. Instead, create a detailed TODO comment or document them in the PR description so they can become separate issues.
|
||||
|
||||
### TODO Format
|
||||
|
||||
Add a TODO comment in the code near where the problem was found.
|
||||
|
||||
**Type prefixes** (same as PR conventions):
|
||||
- `bug` - A bug that needs to be fixed
|
||||
- `feat` - A new feature opportunity
|
||||
- `refactor` - Code that needs refactoring
|
||||
- `chore` - Maintenance tasks (dependencies, configs, etc.)
|
||||
- `test` - Missing or incomplete tests
|
||||
|
||||
**Optional labels** (GitHub labels in brackets):
|
||||
- `[security]` - Security-related issues
|
||||
- `[performance]` - Performance improvements
|
||||
- `[a11y]` - Accessibility issues
|
||||
- `[i18n]` - Internationalization issues
|
||||
- `[breaking]` - Breaking changes
|
||||
- Any other GitHub label relevant to the issue
|
||||
|
||||
```typescript
|
||||
// TODO: type [optional-label] <Brief title>
|
||||
// Problem: <Detailed description of what is wrong>
|
||||
// Location: <File path and function/component name>
|
||||
// Impact: <How this affects the system - severity, affected features>
|
||||
// Suggested fix: <High-level approach to resolve>
|
||||
// Discovered while: <Reference to current PR/issue>
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
// TODO: chore [breaking] Deprecated API usage in notification service
|
||||
// Problem: The notifyUser() function uses the deprecated Meteor.defer() API
|
||||
// which will be removed in the next major version.
|
||||
// Location: apps/meteor/server/services/notifications/notifyUser.ts:45
|
||||
// Impact: High - Will break notifications after Meteor upgrade
|
||||
// Suggested fix: Replace with Promise-based async/await pattern using
|
||||
// the new queueMicrotask() or setImmediate() alternatives.
|
||||
// Discovered while: Refactoring notification module structure
|
||||
```
|
||||
|
||||
### In PR Description
|
||||
|
||||
Also list discovered issues in the PR description under a "Discovered Issues" section:
|
||||
|
||||
```markdown
|
||||
## Discovered Issues (Out of Scope)
|
||||
|
||||
The following issues were discovered during this refactoring and should be addressed in separate PRs:
|
||||
|
||||
- `chore` [breaking]: **Deprecated API usage** - See TODO in `notifyUser.ts:45`
|
||||
- `bug`: **Missing error boundary** - See TODO in `MessageList.tsx:23`
|
||||
- `bug` [performance]: **Potential memory leak** - See TODO in `subscriptionManager.ts:112`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step-by-Step Execution Flow
|
||||
|
||||
### 1. Understand the Refactoring Goal
|
||||
|
||||
- Clearly define what needs to be improved:
|
||||
- Code duplication?
|
||||
- Complex conditionals?
|
||||
- Poor naming?
|
||||
- Missing type safety?
|
||||
- Tight coupling?
|
||||
- Large files/functions?
|
||||
- Identify the scope and boundaries of the refactoring.
|
||||
|
||||
---
|
||||
|
||||
### 2. Analyze Current State
|
||||
|
||||
- Review the existing code structure.
|
||||
- Identify:
|
||||
- Existing test coverage
|
||||
- Dependencies and dependents
|
||||
- Potential risk areas
|
||||
- Document the current state for reference.
|
||||
|
||||
---
|
||||
|
||||
### 3. Ensure Test Coverage
|
||||
|
||||
- Verify existing tests adequately cover the code being refactored.
|
||||
- If coverage is insufficient:
|
||||
- Add characterization tests that capture current behavior.
|
||||
- These tests act as a safety net during refactoring.
|
||||
- Tests must pass before any refactoring begins.
|
||||
|
||||
---
|
||||
|
||||
### 4. Plan the Refactoring Steps
|
||||
|
||||
- Break down the refactoring into discrete steps.
|
||||
- Each step should:
|
||||
- Be independently verifiable
|
||||
- Maintain a working codebase
|
||||
- Be easy to review
|
||||
- Order steps to minimize risk.
|
||||
|
||||
---
|
||||
|
||||
### 5. Execute Refactoring Incrementally
|
||||
|
||||
For each step:
|
||||
|
||||
1. Make the targeted change.
|
||||
2. Run tests to verify behavior preservation.
|
||||
3. Run lint and type checking.
|
||||
4. Commit with a clear message explaining the change.
|
||||
|
||||
Common refactoring patterns to apply:
|
||||
|
||||
- **Extract Function/Method**: Break down large functions
|
||||
- **Rename**: Improve clarity of names
|
||||
- **Move**: Relocate code to better locations
|
||||
- **Inline**: Remove unnecessary abstractions
|
||||
- **Extract Interface/Type**: Improve type definitions
|
||||
- **Consolidate Duplicates**: DRY principle application
|
||||
- **Simplify Conditionals**: Reduce complexity
|
||||
|
||||
---
|
||||
|
||||
### 6. Validate Final State
|
||||
|
||||
After all refactoring steps:
|
||||
|
||||
- All tests pass.
|
||||
- Lint passes.
|
||||
- TypeScript compilation passes.
|
||||
- Build succeeds.
|
||||
- Code review checklist:
|
||||
- Is the code more readable?
|
||||
- Is the code more maintainable?
|
||||
- Is the structure improved?
|
||||
- Are there any regressions?
|
||||
|
||||
---
|
||||
|
||||
### 7. Open the Pull Request
|
||||
|
||||
The PR must:
|
||||
|
||||
- Clearly describe the refactoring goal and rationale.
|
||||
- List the refactoring patterns applied.
|
||||
- Confirm that no behavioral changes were introduced.
|
||||
- Reference any related issues or technical debt items.
|
||||
- Include before/after examples if helpful.
|
||||
|
||||
---
|
||||
|
||||
## Refactoring Categories
|
||||
|
||||
### Structural Refactoring
|
||||
- File/folder reorganization
|
||||
- Module extraction
|
||||
- Dependency restructuring
|
||||
|
||||
### Code Quality Refactoring
|
||||
- Naming improvements
|
||||
- Function decomposition
|
||||
- Duplication removal
|
||||
- Complexity reduction
|
||||
|
||||
### Type Safety Refactoring
|
||||
- Adding explicit types
|
||||
- Removing `any` types
|
||||
- Improving generic usage
|
||||
- Adding type guards
|
||||
|
||||
### Pattern Application
|
||||
- Applying design patterns
|
||||
- Removing anti-patterns
|
||||
- Standardizing approaches
|
||||
|
||||
---
|
||||
|
||||
## Non-Goals
|
||||
|
||||
This agent must NOT:
|
||||
|
||||
- Change external behavior
|
||||
- Fix bugs (create separate issues)
|
||||
- Add new features
|
||||
- Optimize performance (unless part of explicit refactoring goal)
|
||||
- Make changes outside the defined scope
|
||||
- Skip quality gate verification
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
A successful refactoring results in:
|
||||
|
||||
- Improved code quality metrics (readability, maintainability)
|
||||
- All tests passing (no behavioral changes)
|
||||
- Passing CI (tests, lint, TypeScript)
|
||||
- Clear documentation of changes
|
||||
- Easy-to-review Pull Request
|
||||
- No new bugs introduced
|
||||
21
.github/bot-config.yml
vendored
Normal file
21
.github/bot-config.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
bot:
|
||||
name: "@rocket-cat"
|
||||
whitelist:
|
||||
users:
|
||||
- wreiske
|
||||
- TwizzyDizzy
|
||||
- theorenck
|
||||
- JSzaszvari
|
||||
- reetp
|
||||
labels:
|
||||
- "Contributions: welcome"
|
||||
- "Contributions: only core team"
|
||||
- "Feature: Request"
|
||||
- "Feature: Planned"
|
||||
- "type: bug"
|
||||
- "help wanted"
|
||||
- duplicate
|
||||
- enhancement
|
||||
- invalid
|
||||
- question
|
||||
- wontfix
|
||||
30
.github/dependabot.yml
vendored
Normal file
30
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Main repo NPM package
|
||||
- package-ecosystem: npm
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'automerge'
|
||||
|
||||
## EE dependencies
|
||||
- package-ecosystem: npm
|
||||
directory: '/ee/server/services'
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- 'automerge'
|
||||
|
||||
# Maintain dependencies for GitHub Actions
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
groups:
|
||||
# CodeQL steps must all run the same version, so they have to be bumped together
|
||||
codeql-action:
|
||||
patterns:
|
||||
- 'github/codeql-action*'
|
||||
221
.github/history-manual.json
vendored
Normal file
221
.github/history-manual.json
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
{
|
||||
"0.55.0": [{
|
||||
"title": "[BREAK] `getUsersOfRoom` API to return array of objects with user and username, instead of array of strings",
|
||||
"userLogin": "rodrigok",
|
||||
"contributors": []
|
||||
}, {
|
||||
"title": "[FIX] Incoming integrations would break when trying to use the `Store` feature.`",
|
||||
"userLogin": "rodrigok",
|
||||
"contributors": []
|
||||
}, {
|
||||
"title": "[FIX] Removed Deprecated Package rocketchat:sharedsecret`",
|
||||
"userLogin": "rodrigok",
|
||||
"contributors": []
|
||||
}],
|
||||
"0.72.0-rc.0": [{
|
||||
"title": "[BREAK] Support for Cordova (Rocket.Chat Legacy app) has reached End-of-life, support has been discontinued",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": []
|
||||
}],
|
||||
"3.0.0-rc.9": [{
|
||||
"title": "[BREAK] TLS v1.0 and TLS v1.1 were disabled by due to NodeJS update to v12. You can still enable them by using flags like `--tls-min-v1.0` and `--tls-min-v1.1`",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": []
|
||||
}],
|
||||
"3.6.0-rc.0": [{
|
||||
"pr": "18642",
|
||||
"title": "[NEW] Admin option to reset other users’ E2E encryption key",
|
||||
"userLogin": "rodrigok",
|
||||
"contributors": [],
|
||||
"description": "Requires the 2FA password fallback enforcement enabled to work"
|
||||
}],
|
||||
"3.7.3": [{
|
||||
"title": "[FIX] Exception on certain login cases including SAML",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"3.8.3": [{
|
||||
"title": "[FIX] Exception on certain login cases including SAML",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"3.9.1": [{
|
||||
"title": "[FIX] Exception on certain login cases including SAML",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"3.10.5": [{
|
||||
"title": "[FIX] Security Hotfix",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"3.12.0-rc.3": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"3.12.2": [{
|
||||
"title": "[FIX] Bump Livechat widget",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}, {
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego",
|
||||
"g-thome",
|
||||
"KevLehman",
|
||||
"matheusbsilva137"
|
||||
]
|
||||
}],
|
||||
"3.13.2": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego",
|
||||
"KevLehman",
|
||||
"renatobecker"
|
||||
]
|
||||
}],
|
||||
"3.14.2": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego",
|
||||
"KevLehman",
|
||||
"g-thome"
|
||||
]
|
||||
}],
|
||||
"3.14.4": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "ggazzo",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"3.16.3": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"g-thome",
|
||||
"ggazzo",
|
||||
"sampaiodiego",
|
||||
"matheusbsilva137",
|
||||
"pierre-lehnen-rc"
|
||||
]
|
||||
}],
|
||||
"3.18.2": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego",
|
||||
"pierre-lehnen-rc"
|
||||
]
|
||||
}],
|
||||
"3.18.6": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "d-gubert",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"3.18.7": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "d-gubert",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"4.1.1": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"4.3.2": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego",
|
||||
"yash-rajpal",
|
||||
"pierre-lehnen-rc",
|
||||
"gronke"
|
||||
]
|
||||
}],
|
||||
"4.3.3": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"gronke"
|
||||
]
|
||||
}],
|
||||
"4.4.4": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "d-gubert",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"4.4.5": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "d-gubert",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"4.7.3": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "d-gubert",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"4.7.4": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "d-gubert",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"4.8.2": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "sampaiodiego",
|
||||
"contributors": [
|
||||
"sampaiodiego"
|
||||
]
|
||||
}],
|
||||
"5.1.2": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "ggazzo",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"5.3.3": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "ggazzo",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}],
|
||||
"5.4.3": [{
|
||||
"title": "[FIX] Security Hotfix (https://docs.rocket.chat/guides/security/security-updates)",
|
||||
"userLogin": "ggazzo",
|
||||
"contributors": [
|
||||
"ggazzo"
|
||||
]
|
||||
}]
|
||||
}
|
||||
29
.github/issue-close-app.yml
vendored
Normal file
29
.github/issue-close-app.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Config for Close Issue app: https://probot.github.io/apps/close-issue/
|
||||
|
||||
# Comment that will be sent if an issue is judged to be closed
|
||||
comment: |
|
||||
This issue was closed because it does not use our bug report issue template.
|
||||
|
||||
Please make sure to use it and fill it as much as you can so we can provide better and faster support.
|
||||
|
||||
The following sections **must not** be removed, or else the BOT will close it immediately again:
|
||||
|
||||
* Steps to reproduce
|
||||
* Expected behavior
|
||||
* Actual behavior
|
||||
* Server Setup Information
|
||||
* Version of Rocket.Chat Server
|
||||
issueConfigs:
|
||||
# There can be several configs for different kind of issues.
|
||||
- content:
|
||||
# Bug report
|
||||
- "Steps to reproduce"
|
||||
- "Expected behavior"
|
||||
- "Actual behavior"
|
||||
- "Server Setup Information"
|
||||
- "Version of Rocket.Chat Server"
|
||||
- content:
|
||||
# Release issue
|
||||
- "Before Release - Preparation"
|
||||
# The issue is considered to be valid if it includes all keywords from any of these two configs.
|
||||
# Or it will be closed by the app.
|
||||
33
.github/workflows/auto-close-duplicates.yml
vendored
Normal file
33
.github/workflows/auto-close-duplicates.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Auto-close duplicate issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 9 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
auto-close-duplicates:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Auto-close duplicate issues
|
||||
run: bun run scripts/auto-close-duplicates.ts
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
|
||||
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
|
||||
STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
|
||||
128
.github/workflows/ci-code-check.yml
vendored
Normal file
128
.github/workflows/ci-code-check.yml
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
name: Code Checks
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
node-version:
|
||||
required: true
|
||||
type: string
|
||||
deno-version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
env:
|
||||
TOOL_NODE_FLAGS: ${{ vars.TOOL_NODE_FLAGS }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
code-check:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: ${{ matrix.check == 'ts' && 'TypeScript' || 'Code Lint' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
check: ['ts', 'lint']
|
||||
|
||||
steps:
|
||||
- name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0.0
|
||||
with:
|
||||
swap-size-gb: 4
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
deno-version: ${{ inputs.deno-version }}
|
||||
cache-modules: true
|
||||
install: true
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- uses: ./.github/actions/restore-packages
|
||||
|
||||
- name: Restore TypeScript incremental cache
|
||||
id: restore-typecheck
|
||||
if: matrix.check == 'ts'
|
||||
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ./apps/meteor/tsconfig.typecheck.tsbuildinfo
|
||||
key: typecheck-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: |
|
||||
typecheck-cache-${{ runner.os }}-
|
||||
|
||||
- name: Cache observability (typecheck)
|
||||
if: matrix.check == 'ts'
|
||||
run: |
|
||||
{
|
||||
echo "### TypeScript incremental cache"
|
||||
echo "- **exact hit**: \`${{ steps.restore-typecheck.outputs.cache-hit }}\`"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Install Meteor
|
||||
shell: bash
|
||||
run: |
|
||||
# Restore bin from cache
|
||||
set +e
|
||||
METEOR_SYMLINK_TARGET=$(readlink ~/.meteor/meteor)
|
||||
METEOR_TOOL_DIRECTORY=$(dirname "$METEOR_SYMLINK_TARGET")
|
||||
set -e
|
||||
LAUNCHER=$HOME/.meteor/$METEOR_TOOL_DIRECTORY/scripts/admin/launch-meteor
|
||||
if [ -e "$LAUNCHER" ]
|
||||
then
|
||||
echo "Cached Meteor bin found, restoring it"
|
||||
sudo cp "$LAUNCHER" "/usr/local/bin/meteor"
|
||||
else
|
||||
echo "No cached Meteor bin found."
|
||||
fi
|
||||
|
||||
# only install meteor if bin isn't found
|
||||
command -v meteor >/dev/null 2>&1 || curl https://install.meteor.com | sed s/--progress-bar/-sL/g | /bin/sh
|
||||
|
||||
- name: TS TypeCheck
|
||||
if: matrix.check == 'ts'
|
||||
run: yarn turbo run typecheck --concurrency=5
|
||||
|
||||
- name: Save TypeScript incremental cache
|
||||
if: matrix.check == 'ts' && github.ref == 'refs/heads/develop' && github.event_name == 'push'
|
||||
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ./apps/meteor/tsconfig.typecheck.tsbuildinfo
|
||||
key: typecheck-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
- name: Restore ESLint cache
|
||||
id: restore-eslint
|
||||
if: matrix.check == 'lint'
|
||||
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ./apps/meteor/.eslintcache
|
||||
key: eslintcache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: |
|
||||
eslintcache-${{ runner.os }}-
|
||||
|
||||
- name: Cache observability (eslint)
|
||||
if: matrix.check == 'lint'
|
||||
run: |
|
||||
{
|
||||
echo "### ESLint cache"
|
||||
echo "- **exact hit**: \`${{ steps.restore-eslint.outputs.cache-hit }}\`"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
- name: Lint
|
||||
if: matrix.check == 'lint'
|
||||
run: yarn lint
|
||||
|
||||
- name: Save ESLint cache
|
||||
if: matrix.check == 'lint' && github.ref == 'refs/heads/develop' && github.event_name == 'push'
|
||||
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ./apps/meteor/.eslintcache
|
||||
key: eslintcache-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
|
||||
42
.github/workflows/ci-deploy-gh-pages.yml
vendored
Normal file
42
.github/workflows/ci-deploy-gh-pages.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# .github/workflows/ci-preview-deploy.yml
|
||||
name: Deploy GitHub Pages
|
||||
concurrency: preview-deploy-${{ github.ref }}
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
deploy-preview:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
cache-modules: true
|
||||
install: true
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
yarn turbo run build-preview
|
||||
yarn turbo run .:build-preview-move
|
||||
npx indexifier .preview --html --extensions .html > .preview/index.html
|
||||
mv .preview ${{ github.ref_name }}
|
||||
mkdir .preview
|
||||
mv ${{ github.ref_name }} .preview
|
||||
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: .preview
|
||||
keep_files: true
|
||||
344
.github/workflows/ci-test-e2e.yml
vendored
Normal file
344
.github/workflows/ci-test-e2e.yml
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
name: Tests E2E
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
node-version:
|
||||
required: true
|
||||
type: string
|
||||
deno-version:
|
||||
required: true
|
||||
type: string
|
||||
lowercase-repo:
|
||||
required: true
|
||||
type: string
|
||||
gh-docker-tag:
|
||||
required: true
|
||||
type: string
|
||||
enterprise-license:
|
||||
type: string
|
||||
transporter:
|
||||
type: string
|
||||
mongodb-version:
|
||||
default: "['8.0']"
|
||||
required: false
|
||||
type: string
|
||||
release:
|
||||
required: true
|
||||
type: string
|
||||
fips:
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
shard:
|
||||
default: '[1]'
|
||||
required: false
|
||||
type: string
|
||||
total-shard:
|
||||
default: 1
|
||||
required: false
|
||||
type: number
|
||||
retries:
|
||||
default: 0
|
||||
required: false
|
||||
type: number
|
||||
type:
|
||||
required: true
|
||||
type: string
|
||||
coverage:
|
||||
required: false
|
||||
type: string
|
||||
secrets:
|
||||
CR_USER:
|
||||
required: true
|
||||
CR_PAT:
|
||||
required: true
|
||||
QASE_API_TOKEN:
|
||||
required: false
|
||||
REPORTER_ROCKETCHAT_URL:
|
||||
required: false
|
||||
REPORTER_ROCKETCHAT_API_KEY:
|
||||
required: false
|
||||
CODECOV_TOKEN:
|
||||
required: false
|
||||
REPORTER_JIRA_ROCKETCHAT_API_KEY:
|
||||
required: false
|
||||
NPM_TOKEN:
|
||||
required: false
|
||||
|
||||
env:
|
||||
MONGO_URL: mongodb://localhost:27017/rocketchat?replicaSet=rs0&directConnection=true
|
||||
TOOL_NODE_FLAGS: ${{ vars.TOOL_NODE_FLAGS }}
|
||||
LOWERCASE_REPOSITORY: ${{ inputs.lowercase-repo }}
|
||||
DOCKER_TAG: ${{ inputs.gh-docker-tag }}-amd64
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
env:
|
||||
# if building for production on develop branch or release, add suffix for coverage images
|
||||
DOCKER_TAG_SUFFIX_ROCKETCHAT: ${{ inputs.coverage == matrix.mongodb-version && (github.event_name == 'release' || github.ref == 'refs/heads/develop') && '-cov' || '' }}
|
||||
MONGODB_VERSION: ${{ matrix.mongodb-version }}
|
||||
COVERAGE_DIR: '/tmp/coverage/${{ startsWith(inputs.type, ''api'') && ''api'' || inputs.type }}'
|
||||
COVERAGE_FILE_NAME: '${{ inputs.type }}-${{ matrix.shard }}.json'
|
||||
COVERAGE_REPORTER: ${{ inputs.coverage == matrix.mongodb-version && 'json' || '' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
mongodb-version: ${{ fromJSON(inputs.mongodb-version) }}
|
||||
shard: ${{ fromJSON(inputs.shard) }}
|
||||
|
||||
name: MongoDB ${{ matrix.mongodb-version }}${{ inputs.coverage == matrix.mongodb-version && ' coverage' || '' }} (${{ matrix.shard }}/${{ inputs.total-shard }})
|
||||
|
||||
steps:
|
||||
- name: Collect Workflow Telemetry
|
||||
if: inputs.type == 'perf'
|
||||
uses: catchpoint/workflow-telemetry-action@94c3c3d9567a0205de6da68a76c428ce4e769af1 # v2.0.0
|
||||
with:
|
||||
theme: dark
|
||||
job_summary: true
|
||||
comment_on_pr: false
|
||||
|
||||
- name: Setup kernel limits
|
||||
run: |
|
||||
echo "500 65535" > sudo tee -a /proc/sys/net/ipv4/ip_local_port_range
|
||||
sudo sysctl -w net.ipv4.tcp_mem="383865 511820 2303190"
|
||||
|
||||
echo fs.file-max=20000500 | sudo tee -a /etc/sysctl.conf
|
||||
echo fs.nr_open=20000500 | sudo tee -a /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: (github.event.pull_request.head.repo.full_name == github.repository || github.event_name == 'release' || github.ref == 'refs/heads/develop') && github.actor != 'dependabot[bot]'
|
||||
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.CR_USER }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
deno-version: ${{ inputs.deno-version }}
|
||||
cache-modules: true
|
||||
install: true
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- uses: ./.github/actions/restore-packages
|
||||
|
||||
# Download Docker images from build artifacts
|
||||
- name: Download Docker images
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop'
|
||||
with:
|
||||
pattern: ${{ inputs.release == 'ce' && 'docker-image-rocketchat-amd64-coverage' || (inputs.fips && 'docker-image-*-amd64-fips' || 'docker-image-*-amd64-coverage') }}
|
||||
path: /tmp/docker-images
|
||||
merge-multiple: true
|
||||
|
||||
# Load Docker images
|
||||
- name: Load Docker images
|
||||
if: github.event.pull_request.head.repo.full_name != github.repository && github.event_name != 'release' && github.ref != 'refs/heads/develop'
|
||||
shell: bash
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
# Load all downloaded images
|
||||
for image_file in /tmp/docker-images/*.tar; do
|
||||
if [ -f "$image_file" ]; then
|
||||
echo "Loading image from $image_file"
|
||||
docker load -i "$image_file"
|
||||
rm "$image_file"
|
||||
fi
|
||||
done
|
||||
|
||||
# List loaded images
|
||||
docker images
|
||||
|
||||
- name: Set DEBUG_LOG_LEVEL (debug enabled)
|
||||
if: runner.debug == '1'
|
||||
run: echo "DEBUG_LOG_LEVEL=2" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Start httpbin container and wait for it to be ready
|
||||
if: startsWith(inputs.type, 'api')
|
||||
run: |
|
||||
docker compose -f docker-compose-ci.yml up -d httpbin
|
||||
|
||||
- name: Prepare code coverage directory
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
mkdir -p "$COVERAGE_DIR"
|
||||
chmod 777 "$COVERAGE_DIR"
|
||||
|
||||
- name: Start containers for CE
|
||||
if: inputs.release == 'ce'
|
||||
env:
|
||||
# API tests intentionally invoke deprecated DDP methods through
|
||||
# /v1/method.call/:method. TEST_MODE='api' keeps every other test
|
||||
# behavior on (rate-limiter bypass, short cache TTLs) while letting
|
||||
# the deprecation logger log without throwing. Other suites use the
|
||||
# docker-compose default of TEST_MODE='true'.
|
||||
TEST_MODE: ${{ startsWith(inputs.type, 'api') && 'api' || 'true' }}
|
||||
TEST_TYPE: ${{ inputs.type }}
|
||||
run: |
|
||||
# when we are testing CE, we only need to start the rocketchat container (plus mock-server for the api suite)
|
||||
services=(rocketchat)
|
||||
if [ "$TEST_TYPE" == "api" ]; then
|
||||
services+=(mock-server)
|
||||
fi
|
||||
DEBUG_LOG_LEVEL=${DEBUG_LOG_LEVEL:-0} docker compose -f docker-compose-ci.yml up -d "${services[@]}" --wait
|
||||
|
||||
- name: Start containers for EE
|
||||
if: inputs.release == 'ee'
|
||||
env:
|
||||
ENTERPRISE_LICENSE: ${{ inputs.enterprise-license }}
|
||||
TRANSPORTER: ${{ inputs.transporter }}
|
||||
COMPOSE_PROFILES: ${{ inputs.type == 'api' && 'api' || '' }}
|
||||
TEST_MODE: ${{ startsWith(inputs.type, 'api') && 'api' || 'true' }}
|
||||
APPS_ENGINE_RUNTIME_BACKEND: ${{ inputs.type == 'api-apps-deno' && 'deno' || '' }}
|
||||
FIPS_OVERRIDE: ${{ inputs.fips && '-f docker-compose-ci.fips.yml' || '' }}
|
||||
run: |
|
||||
read -r -a fips_override <<< "$FIPS_OVERRIDE"
|
||||
DEBUG_LOG_LEVEL=${DEBUG_LOG_LEVEL:-0} docker compose -f docker-compose-ci.yml "${fips_override[@]}" up -d --wait
|
||||
|
||||
- uses: ./.github/actions/setup-playwright
|
||||
if: inputs.type == 'ui'
|
||||
|
||||
- name: Wait services to start up
|
||||
if: inputs.release == 'ee'
|
||||
run: |
|
||||
docker ps
|
||||
|
||||
until docker compose -f docker-compose-ci.yml logs ddp-streamer-service | grep -q "NetworkBroker started successfully"; do
|
||||
echo "Waiting 'ddp-streamer' to start up"
|
||||
((c++)) && ((c==10)) && docker compose -f docker-compose-ci.yml logs ddp-streamer-service && exit 1
|
||||
sleep 10
|
||||
done;
|
||||
|
||||
- name: Remove unused Docker images
|
||||
run: docker system prune -af
|
||||
|
||||
- name: E2E Test API
|
||||
if: inputs.type == 'api'
|
||||
working-directory: ./apps/meteor
|
||||
env:
|
||||
WEBHOOK_TEST_URL: 'http://httpbin'
|
||||
IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }}
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
npm run testapi || s=$?
|
||||
|
||||
docker compose -f ../../docker-compose-ci.yml stop
|
||||
|
||||
ls -la "$COVERAGE_DIR"
|
||||
exit "${s:-0}"
|
||||
|
||||
# This step should be temporary, only here until we remove the deno-runtime
|
||||
- name: E2E Test API (apps + deno-runtime)
|
||||
if: (inputs.type == 'api-apps-deno' && inputs.release == 'ee')
|
||||
working-directory: ./apps/meteor
|
||||
env:
|
||||
WEBHOOK_TEST_URL: 'http://httpbin'
|
||||
IS_EE: 'true'
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
npm run testapi:apps || s=$?
|
||||
|
||||
docker compose -f ../../docker-compose-ci.yml stop
|
||||
|
||||
ls -la "$COVERAGE_DIR"
|
||||
exit "${s:-0}"
|
||||
|
||||
- name: E2E Test API (Livechat)
|
||||
if: inputs.type == 'api-livechat'
|
||||
working-directory: ./apps/meteor
|
||||
env:
|
||||
WEBHOOK_TEST_URL: 'http://httpbin'
|
||||
IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }}
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
npm run testapi:livechat || s=$?
|
||||
|
||||
docker compose -f ../../docker-compose-ci.yml stop
|
||||
|
||||
ls -la "$COVERAGE_DIR"
|
||||
exit "${s:-0}"
|
||||
|
||||
- name: E2E Test UI (${{ matrix.shard }}/${{ inputs.total-shard }})
|
||||
if: inputs.type == 'ui'
|
||||
env:
|
||||
E2E_COVERAGE: ${{ inputs.coverage == matrix.mongodb-version && 'true' || '' }}
|
||||
IS_EE: ${{ inputs.release == 'ee' && 'true' || '' }}
|
||||
REPORTER_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_ROCKETCHAT_API_KEY }}
|
||||
REPORTER_ROCKETCHAT_URL: ${{ secrets.REPORTER_ROCKETCHAT_URL }}
|
||||
REPORTER_JIRA_ROCKETCHAT_API_KEY: ${{ secrets.REPORTER_JIRA_ROCKETCHAT_API_KEY }}
|
||||
REPORTER_ROCKETCHAT_REPORT: ${{ github.event.pull_request.draft != 'true' && secrets.REPORTER_ROCKETCHAT_URL != '' && 'true' || '' }}
|
||||
REPORTER_ROCKETCHAT_RUN: ${{ github.run_number }}
|
||||
REPORTER_ROCKETCHAT_BRANCH: ${{ github.ref }}
|
||||
REPORTER_ROCKETCHAT_DRAFT: ${{ github.event.pull_request.draft }}
|
||||
REPORTER_ROCKETCHAT_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
REPORTER_ROCKETCHAT_AUTHOR: ${{ github.event.pull_request.user.login }}
|
||||
REPORTER_ROCKETCHAT_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
REPORTER_ROCKETCHAT_PR: ${{ github.event.pull_request.number }}
|
||||
QASE_API_TOKEN: ${{ secrets.QASE_API_TOKEN }}
|
||||
QASE_REPORT: ${{ github.ref == 'refs/heads/develop' && 'true' || '' }}
|
||||
CI: true
|
||||
PLAYWRIGHT_RETRIES: ${{ inputs.retries }}
|
||||
E2E_SHARD: ${{ matrix.shard }}
|
||||
E2E_TOTAL_SHARD: ${{ inputs.total-shard }}
|
||||
working-directory: ./apps/meteor
|
||||
run: |
|
||||
set -o xtrace
|
||||
|
||||
yarn prepare
|
||||
yarn test:e2e --shard="$E2E_SHARD/$E2E_TOTAL_SHARD"
|
||||
|
||||
- name: Merge ui coverage files
|
||||
if: inputs.type == 'ui' && inputs.coverage == matrix.mongodb-version
|
||||
working-directory: ./apps/meteor
|
||||
run: |
|
||||
npx nyc merge .nyc_output "${COVERAGE_DIR}/${COVERAGE_FILE_NAME}"
|
||||
ls -la "$COVERAGE_DIR" || true
|
||||
|
||||
- name: Store playwright test trace
|
||||
if: inputs.type == 'ui' && always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: playwright-test-trace-${{ inputs.release }}${{ inputs.fips && '-fips' || '' }}-${{ matrix.mongodb-version }}-${{ matrix.shard }}
|
||||
path: ./apps/meteor/tests/e2e/.playwright*
|
||||
include-hidden-files: true
|
||||
|
||||
- name: Show server logs if E2E test failed
|
||||
if: failure()
|
||||
run: docker compose -f docker-compose-ci.yml logs rocketchat authorization-service queue-worker-service ddp-streamer-service account-service presence-service omnichannel-transcript-service
|
||||
|
||||
- name: Show mongo logs if E2E test failed
|
||||
if: failure()
|
||||
run: docker compose -f docker-compose-ci.yml logs mongo
|
||||
|
||||
- name: Show traefik logs if E2E test failed
|
||||
if: failure()
|
||||
run: docker compose -f docker-compose-ci.yml logs traefik
|
||||
|
||||
- name: Store coverage
|
||||
if: inputs.coverage == matrix.mongodb-version
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: coverage-${{ inputs.type }}-${{ matrix.shard }}
|
||||
path: /tmp/coverage
|
||||
include-hidden-files: true
|
||||
62
.github/workflows/ci-test-storybook.yml
vendored
Normal file
62
.github/workflows/ci-test-storybook.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Test Storybook
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
node-version:
|
||||
required: true
|
||||
type: string
|
||||
deno-version:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
secrets:
|
||||
CODECOV_TOKEN:
|
||||
required: true
|
||||
NPM_TOKEN:
|
||||
required: false
|
||||
|
||||
env:
|
||||
TOOL_NODE_FLAGS: ${{ vars.TOOL_NODE_FLAGS }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: Test Storybook
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
deno-version: ${{ inputs.deno-version }}
|
||||
cache-modules: true
|
||||
install: true
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- uses: ./.github/actions/restore-packages
|
||||
|
||||
- uses: ./.github/actions/setup-playwright
|
||||
|
||||
- name: Run tests
|
||||
run: yarn test-storybook
|
||||
env:
|
||||
STORYBOOK_DISABLE_TELEMETRY: 1
|
||||
|
||||
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||
with:
|
||||
flags: unit
|
||||
verbose: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
# tests don't re-run on the develop push, so the merge queue run (same SHA
|
||||
# that lands on develop) provides the develop coverage baseline
|
||||
override_branch: ${{ github.event_name == 'merge_group' && github.event.merge_group.base_ref == 'refs/heads/develop' && 'develop' || '' }}
|
||||
62
.github/workflows/ci-test-unit.yml
vendored
Normal file
62
.github/workflows/ci-test-unit.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
name: Tests Unit
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
node-version:
|
||||
required: true
|
||||
type: string
|
||||
deno-version:
|
||||
required: true
|
||||
type: string
|
||||
enterprise-license:
|
||||
required: false
|
||||
type: string
|
||||
secrets:
|
||||
CODECOV_TOKEN:
|
||||
required: false
|
||||
NPM_TOKEN:
|
||||
required: false
|
||||
|
||||
env:
|
||||
MONGO_URL: mongodb://localhost:27017/rocketchat?replicaSet=rs0&directConnection=true
|
||||
TOOL_NODE_FLAGS: ${{ vars.TOOL_NODE_FLAGS }}
|
||||
ENTERPRISE_LICENSE: ${{ inputs.enterprise-license }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
name: Unit Tests
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
deno-version: ${{ inputs.deno-version }}
|
||||
cache-modules: true
|
||||
install: true
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- uses: ./.github/actions/restore-packages
|
||||
|
||||
- name: Unit Test
|
||||
run: yarn testunit --concurrency=1
|
||||
|
||||
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
|
||||
with:
|
||||
flags: unit
|
||||
verbose: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
# tests don't re-run on the develop push, so the merge queue run (same SHA
|
||||
# that lands on develop) provides the develop coverage baseline
|
||||
override_branch: ${{ github.event_name == 'merge_group' && github.event.merge_group.base_ref == 'refs/heads/develop' && 'develop' || '' }}
|
||||
1333
.github/workflows/ci.yml
vendored
Normal file
1333
.github/workflows/ci.yml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
57
.github/workflows/codeql-analysis.yml
vendored
Normal file
57
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: 'Code scanning - action'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- dependabot/**
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 13 * * *'
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
with:
|
||||
languages: javascript
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4
|
||||
85
.github/workflows/dedupe-issues.yml
vendored
Normal file
85
.github/workflows/dedupe-issues.yml
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
name: Rocket.Chat Issue Dedupe
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: 'Issue number to process for duplicate detection'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
dedupe-issues:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Run Claude Code slash command
|
||||
uses: anthropics/claude-code-base-action@e8132bc5e637a42c27763fc757faa37e1ee43b34 # v0.0.63beta
|
||||
with:
|
||||
prompt: '/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}'
|
||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||||
model: 'claude-sonnet-4-5-20250929'
|
||||
claude_env: |
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Log duplicate comment event to Statsig
|
||||
if: always()
|
||||
env:
|
||||
STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
|
||||
run: |
|
||||
ISSUE_NUMBER=${{ github.event.issue.number || inputs.issue_number }}
|
||||
REPO=${{ github.repository }}
|
||||
|
||||
if [ -z "$STATSIG_API_KEY" ]; then
|
||||
echo "STATSIG_API_KEY not found, skipping Statsig logging"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Prepare the event payload
|
||||
EVENT_PAYLOAD=$(jq -n \
|
||||
--arg issue_number "$ISSUE_NUMBER" \
|
||||
--arg repo "$REPO" \
|
||||
--arg triggered_by "${{ github.event_name }}" \
|
||||
--arg actor "${{ github.actor }}" \
|
||||
'{
|
||||
events: [{
|
||||
eventName: "github_duplicate_comment_added",
|
||||
value: 1,
|
||||
metadata: {
|
||||
repository: $repo,
|
||||
issue_number: ($issue_number | tonumber),
|
||||
triggered_by: $triggered_by,
|
||||
workflow_run_id: "${{ github.run_id }}",
|
||||
actor: $actor
|
||||
},
|
||||
time: (now | floor | tostring)
|
||||
}]
|
||||
}')
|
||||
|
||||
# Send to Statsig API
|
||||
echo "Logging duplicate comment event to Statsig for issue #${ISSUE_NUMBER}"
|
||||
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
|
||||
-d "$EVENT_PAYLOAD")
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
BODY=$(echo "$RESPONSE" | head -n-1)
|
||||
|
||||
if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
|
||||
echo "Successfully logged duplicate comment event for issue #${ISSUE_NUMBER}"
|
||||
else
|
||||
echo "Failed to log duplicate comment event for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
|
||||
fi
|
||||
42
.github/workflows/pr-update-description.yml
vendored
Normal file
42
.github/workflows/pr-update-description.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: 'Release PR Description'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
update-pr:
|
||||
runs-on: ubuntu-24.04
|
||||
if: startsWith(github.head_ref, 'release-')
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.CI_PAT }}
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
cache-modules: true
|
||||
install: true
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- name: Build packages
|
||||
run: yarn build
|
||||
|
||||
- name: Update PR description
|
||||
uses: ./packages/release-action
|
||||
with:
|
||||
action: update-pr-description
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.CI_PAT }}
|
||||
79
.github/workflows/release.yml
vendored
Normal file
79
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
name: Release
|
||||
|
||||
# Single entry point for every path that publishes to npm. npm allows one trusted
|
||||
# publisher per package and validates the entry-point workflow filename, so `cut`,
|
||||
# `next` and `publish-final` all have to run from this file.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: '28 21 20 * *' # run at minute 28 to avoid the chance of delay due to high load on GH
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
name:
|
||||
type: choice
|
||||
description: Release type
|
||||
default: next
|
||||
required: true
|
||||
options:
|
||||
- next
|
||||
- patch
|
||||
- cut
|
||||
base-ref:
|
||||
description: Base version
|
||||
default: develop
|
||||
required: false
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
env:
|
||||
HUSKY: 0
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # npm trusted publishing (OIDC)
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ github.event_name == 'schedule' && github.ref_name || github.event_name == 'workflow_dispatch' && inputs.base-ref || '' }}
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.CI_PAT }}
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: ./.github/actions/setup-node
|
||||
with:
|
||||
cache-modules: true
|
||||
install: true
|
||||
# Transitional: npm attempts the OIDC exchange first and overrides this token on
|
||||
# success, so it only takes effect when the exchange fails. That keeps releases
|
||||
# alive while packages are registered as trusted publishers one by one. Remove
|
||||
# once every package reports a non-null dist.attestations — see docs/npm-publishing.md.
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
# Node 22 bundles npm 10, trusted publishing needs >= 11.5.1
|
||||
- name: Setup npm
|
||||
run: |
|
||||
npm install -g npm@^11.15.0
|
||||
npm --version
|
||||
|
||||
- uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
|
||||
- name: Build packages
|
||||
run: yarn build
|
||||
|
||||
- name: Release
|
||||
uses: ./packages/release-action
|
||||
with:
|
||||
action: ${{ github.event_name == 'push' && 'publish-final' || github.event_name == 'schedule' && 'next' || inputs.name }}
|
||||
base-ref: ${{ github.event_name == 'schedule' && github.ref_name || github.event_name == 'workflow_dispatch' && inputs.base-ref || '' }}
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # transitional, see the Setup NodeJS step
|
||||
GITHUB_TOKEN: ${{ secrets.CI_PAT }}
|
||||
20
.github/workflows/stale.yml
vendored
Normal file
20
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Close inactive issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */6 * * *'
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0
|
||||
with:
|
||||
days-before-issue-stale: 14
|
||||
days-before-issue-close: 14
|
||||
any-of-labels: 'stat: need more info,stat: waiting response'
|
||||
stale-issue-label: 'stat: no response'
|
||||
stale-issue-message: 'This issue has been marked as stale because there has been no further activity in the last 10 days. If the issue remains stale for the next 4 days (a total of 14 days with no activity), then it will be assumed that the question has been resolved and the issue will be automatically closed.'
|
||||
close-issue-message: 'This issue was closed because it has been inactive for 14 days since being marked as stale.'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
58
.github/workflows/todo.yml
vendored
Normal file
58
.github/workflows/todo.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
name: Create issues from TODOs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
importAll:
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
description: Enable, if you want to import all TODOs. Runs on checked out branch! Only use if you're sure what you are doing.
|
||||
sha:
|
||||
default: ''
|
||||
required: false
|
||||
type: string
|
||||
description: 'A commit SHA or range (e.g. "abc123" or "abc123...def456"). Single SHA compares against its parent.'
|
||||
path:
|
||||
default: ''
|
||||
required: false
|
||||
type: string
|
||||
description: 'Import TODOs from a specific path (e.g. "apps/meteor/client" or "packages/core-typings/src/IMessage.ts").'
|
||||
push:
|
||||
branches: # do not set multiple branches, todos might be added and then get referenced by themselves in case of a merge
|
||||
- develop
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
repository-projects: read
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
todos:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
working-directory: scripts/todo-issue
|
||||
|
||||
- name: Create issues from TODOs
|
||||
run: bun run src/index.ts
|
||||
working-directory: scripts/todo-issue
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
|
||||
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
|
||||
GITHUB_SHA: ${{ github.sha }}
|
||||
BEFORE_SHA: ${{ github.event.before }}
|
||||
IMPORT_ALL: ${{ inputs.importAll || 'false' }}
|
||||
SHA_INPUT: ${{ inputs.sha || '' }}
|
||||
PATH_FILTER: ${{ inputs.path || '' }}
|
||||
47
.github/workflows/update-version-durability.yml
vendored
Normal file
47
.github/workflows/update-version-durability.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
name: Update Version Durability
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
inputs:
|
||||
LTS_VERSIONS:
|
||||
required: false
|
||||
type: string
|
||||
secrets:
|
||||
CI_PAT:
|
||||
required: true
|
||||
D360_TOKEN:
|
||||
required: true
|
||||
D360_USER_ID:
|
||||
required: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
update-versions:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version: 24.15.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd ./.github/actions/update-version-durability
|
||||
npm install
|
||||
|
||||
- name: Update Version Durability
|
||||
uses: ./.github/actions/update-version-durability
|
||||
with:
|
||||
LTS_VERSIONS: ${{ inputs.LTS_VERSIONS != '' && inputs.LTS_VERSIONS || vars.LTS_VERSIONS }}
|
||||
GH_TOKEN: ${{ secrets.CI_PAT }}
|
||||
D360_TOKEN: ${{ secrets.D360_TOKEN }}
|
||||
D360_ARTICLE_ID: 800f8d52-409d-478d-b560-f82a2c0eb7fb
|
||||
D360_USER_ID: ${{ secrets.D360_USER_ID }}
|
||||
PUBLISH: true
|
||||
64
.gitignore
vendored
Normal file
64
.gitignore
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
coverage
|
||||
|
||||
# next.js
|
||||
.next/
|
||||
out/
|
||||
build
|
||||
dist
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
storybook-static
|
||||
# turbo
|
||||
.turbo
|
||||
|
||||
# yarn
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
.nvmrc
|
||||
.idea/
|
||||
.exrc
|
||||
.history
|
||||
.envrc
|
||||
|
||||
.preview
|
||||
|
||||
*.sublime-workspace
|
||||
|
||||
**/.vim/
|
||||
|
||||
data/
|
||||
!**/tests/data/
|
||||
registration.yaml
|
||||
|
||||
storybook-static
|
||||
development/tempo-data/
|
||||
|
||||
.env
|
||||
19
.gitpod/.gitpod.yml
Normal file
19
.gitpod/.gitpod.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
tasks:
|
||||
- init: |
|
||||
nvm install $(jq -r .engines.node package.json) &&
|
||||
curl https://install.meteor.com/?release=$(
|
||||
curl -so- https://raw.githubusercontent.com/RocketChat/Rocket.Chat/develop/apps/meteor/.meteor/release | cut -d@ -f2
|
||||
) | sh &&
|
||||
export PATH=$PATH:/home/gitpod/.meteor &&
|
||||
yarn &&
|
||||
export ROOT_URL=$(gp url 3000)
|
||||
command: yarn dsv
|
||||
|
||||
ports:
|
||||
- port: 3000
|
||||
visibility: public
|
||||
onOpen: open-preview
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- esbenp.prettier-vscode
|
||||
15
.gitpod/automations.yaml
Normal file
15
.gitpod/automations.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
services:
|
||||
development-server:
|
||||
name: Rocket.Chat development server
|
||||
description: Starts the Rocket.Chat development server (yarn dsv)
|
||||
triggeredBy:
|
||||
- postDevcontainerStart
|
||||
- manual
|
||||
commands:
|
||||
start: |
|
||||
yarn
|
||||
yarn dsv
|
||||
ready: |
|
||||
export ROOT_URL=$(gitpod environment port open 3000 --name "Rocket.Chat application" | sed 's|https://||')
|
||||
echo $ROOT_URL
|
||||
gitpod environment port open 3000 --name "Rocket.Chat application"
|
||||
74
.houston/metadata.js
Normal file
74
.houston/metadata.js
Normal file
@@ -0,0 +1,74 @@
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
const getMongoVersion = async function({ version, git }) {
|
||||
try {
|
||||
const workflows = await git.show([`${ version }:.github/workflows/ci.yml`]);
|
||||
|
||||
const mongoMatch = workflows.match(/compatibleMongoVersions\\": \[([^\]]+)\]/);
|
||||
if (!mongoMatch) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return mongoMatch[1].replace(/["'\\ ]/g, '').split(',');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const getNodeNpmVersions = async function({ version, git, request }) {
|
||||
try {
|
||||
const meteorRelease = await git.show([`${ version }:apps/meteor/.meteor/release`]);
|
||||
if (!/^METEOR@(\d+\.){1,2}\d/.test(meteorRelease)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const meteorVersion = meteorRelease.replace(/\n|\s/g, '');
|
||||
|
||||
const requestResult = await request(`https://raw.githubusercontent.com/meteor/meteor/release/${ meteorVersion }/scripts/build-dev-bundle-common.sh`);
|
||||
|
||||
return {
|
||||
node_version: requestResult.match(/NODE_VERSION=((?:\d+\.){2}\d+)/m)[1],
|
||||
npm_version: requestResult.match(/NPM_VERSION=((?:\d+\.){2}\d+)/m)[1],
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
const getAppsEngineVersion = async function({ version, git }) {
|
||||
try {
|
||||
const result = execSync('yarn why @rocket.chat/apps-engine --json');
|
||||
|
||||
const resultString = result.toString();
|
||||
|
||||
const match = resultString.match(/"@rocket\.chat\/meteor@workspace:apps\/meteor".*"@rocket\.chat\/apps\-engine@[^#]+#npm:([^"]+)"/);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
module.exports = async function({ version, git, request }) {
|
||||
const mongo_versions = await getMongoVersion({ version, git });
|
||||
const apps_engine_version = await getAppsEngineVersion({ version, git });
|
||||
|
||||
const {
|
||||
node_version,
|
||||
npm_version,
|
||||
} = await getNodeNpmVersions({ version, git, request });
|
||||
|
||||
return {
|
||||
node_version,
|
||||
npm_version,
|
||||
apps_engine_version,
|
||||
mongo_versions,
|
||||
};
|
||||
};
|
||||
|
||||
2
.houston/templates/prs.hbs
Normal file
2
.houston/templates/prs.hbs
Normal file
@@ -0,0 +1,2 @@
|
||||
{{> versions}}
|
||||
{{> _prs}}
|
||||
16
.houston/templates/versions.hbs
Normal file
16
.houston/templates/versions.hbs
Normal file
@@ -0,0 +1,16 @@
|
||||
{{#if (or release.node_version release.npm_version release.mongo_versions)}}
|
||||
|
||||
### Engine versions
|
||||
{{#if release.node_version}}
|
||||
- Node: `{{ release.node_version }}`
|
||||
{{/if}}
|
||||
{{#if release.npm_version}}
|
||||
- NPM: `{{ release.npm_version }}`
|
||||
{{/if}}
|
||||
{{#if release.mongo_versions}}
|
||||
- MongoDB: `{{ join release.mongo_versions ', ' }}`
|
||||
{{/if}}
|
||||
{{#if release.apps_engine_version}}
|
||||
- Apps-Engine: `{{ release.apps_engine_version }}`
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
20
.kodiak.toml
Normal file
20
.kodiak.toml
Normal file
@@ -0,0 +1,20 @@
|
||||
# .kodiak.toml
|
||||
version = 1
|
||||
|
||||
[merge]
|
||||
method = "squash"
|
||||
automerge_label = ["stat: ready to merge", "automerge"]
|
||||
block_on_neutral_required_check_runs = true
|
||||
blocking_labels = ["stat: needs QA", "Invalid PR Title", "do not merge"]
|
||||
prioritize_ready_to_merge = true
|
||||
|
||||
[merge.message]
|
||||
title = "pull_request_title"
|
||||
body = "empty"
|
||||
include_coauthors=true
|
||||
|
||||
[merge.automerge_dependencies]
|
||||
versions = ["minor", "patch"]
|
||||
usernames = ["dependabot"]
|
||||
[approve]
|
||||
auto_approve_usernames = ["dependabot"]
|
||||
12
.prettierrc
Normal file
12
.prettierrc
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"semi": true,
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "lf",
|
||||
"jsxSingleQuote": true,
|
||||
"printWidth": 140,
|
||||
"quoteProps": "consistent",
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"useTabs": true
|
||||
}
|
||||
1
.tool-versions
Normal file
1
.tool-versions
Normal file
@@ -0,0 +1 @@
|
||||
deno 2.3.1
|
||||
35
.vscode/client.code-snippets
vendored
Normal file
35
.vscode/client.code-snippets
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Storybook stories module for React component": {
|
||||
"scope": "typescriptreact",
|
||||
"prefix": "sbmodule",
|
||||
"body": [
|
||||
"import type { Meta, StoryFn } from '@storybook/react';",
|
||||
"",
|
||||
"import $1 from './$1';",
|
||||
"",
|
||||
"export default {",
|
||||
"\ttitle: '$2',",
|
||||
"\tcomponent: $1,",
|
||||
"} satisfies Meta<typeof $1>;",
|
||||
"",
|
||||
"export const Example: StoryFn<typeof $1> = (args) => <$1 {...args} />;",
|
||||
]
|
||||
},
|
||||
"Storybook meta": {
|
||||
"scope": "typescriptreact",
|
||||
"prefix": "sbmeta",
|
||||
"body": [
|
||||
"export default {",
|
||||
"\ttitle: '$1',",
|
||||
"\tcomponent: $2,",
|
||||
"} satisfies Meta<typeof $2>;"
|
||||
]
|
||||
},
|
||||
"Storybook story": {
|
||||
"scope": "typescriptreact",
|
||||
"prefix": "sbstory",
|
||||
"body": [
|
||||
"export const $1: StoryFn<typeof $2> = (args) => <$2 {...args} />;"
|
||||
]
|
||||
}
|
||||
}
|
||||
20
.vscode/settings.json
vendored
Normal file
20
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"cSpell.words": [
|
||||
"autotranslate",
|
||||
"ciphertext",
|
||||
"Contextualbar",
|
||||
"fname",
|
||||
"Gazzodown",
|
||||
"katex",
|
||||
"listbox",
|
||||
"livechat",
|
||||
"oauthapps",
|
||||
"omnichannel",
|
||||
"photoswipe",
|
||||
"proxify",
|
||||
"searchbox",
|
||||
"tmid",
|
||||
"tshow"
|
||||
]
|
||||
}
|
||||
144
.yarn/patches/@react-aria-i18n-npm-3.12.5-435edff786.patch
Normal file
144
.yarn/patches/@react-aria-i18n-npm-3.12.5-435edff786.patch
Normal file
@@ -0,0 +1,144 @@
|
||||
diff --git a/dist/import.mjs b/dist/import.mjs
|
||||
index 668b87f9fbf77162f4baa4b02fe3586c3a2c0b26..6b6dc85b39196597504df1a287495a24ce3c0831 100644
|
||||
--- a/dist/import.mjs
|
||||
+++ b/dist/import.mjs
|
||||
@@ -1,31 +1,7 @@
|
||||
-import {I18nProvider as $18f2051aff69b9bf$export$a54013f0d02a8f82, useLocale as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7} from "./context.mjs";
|
||||
-import {useMessageFormatter as $321bc95feeb923dd$export$ec23bf898b1eed85} from "./useMessageFormatter.mjs";
|
||||
-import {useLocalizedStringDictionary as $fca6afa0e843324b$export$87b761675e8eaa10, useLocalizedStringFormatter as $fca6afa0e843324b$export$f12b703ca79dfbb1} from "./useLocalizedStringFormatter.mjs";
|
||||
-import {useListFormatter as $33bf17300c498528$export$a2f47a3d2973640} from "./useListFormatter.mjs";
|
||||
-import {useDateFormatter as $896ba0a80a8f4d36$export$85fd5fdf27bacc79} from "./useDateFormatter.mjs";
|
||||
-import {useNumberFormatter as $a916eb452884faea$export$b7a616150fdb9f44} from "./useNumberFormatter.mjs";
|
||||
-import {useCollator as $325a3faab7a68acd$export$a16aca283550c30d} from "./useCollator.mjs";
|
||||
-import {useFilter as $bb77f239b46e8c72$export$3274cf84b703fff} from "./useFilter.mjs";
|
||||
-
|
||||
-/*
|
||||
- * Copyright 2020 Adobe. All rights reserved.
|
||||
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
- * you may not use this file except in compliance with the License. You may obtain a copy
|
||||
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
- *
|
||||
- * Unless required by applicable law or agreed to in writing, software distributed under
|
||||
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
- * OF ANY KIND, either express or implied. See the License for the specific language
|
||||
- * governing permissions and limitations under the License.
|
||||
- */
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-export {$18f2051aff69b9bf$export$a54013f0d02a8f82 as I18nProvider, $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 as useLocale, $321bc95feeb923dd$export$ec23bf898b1eed85 as useMessageFormatter, $fca6afa0e843324b$export$f12b703ca79dfbb1 as useLocalizedStringFormatter, $fca6afa0e843324b$export$87b761675e8eaa10 as useLocalizedStringDictionary, $33bf17300c498528$export$a2f47a3d2973640 as useListFormatter, $896ba0a80a8f4d36$export$85fd5fdf27bacc79 as useDateFormatter, $a916eb452884faea$export$b7a616150fdb9f44 as useNumberFormatter, $325a3faab7a68acd$export$a16aca283550c30d as useCollator, $bb77f239b46e8c72$export$3274cf84b703fff as useFilter};
|
||||
-//# sourceMappingURL=module.js.map
|
||||
+import {I18nProvider as $18f2051aff69b9bf$export$a54013f0d02a8f82, useLocale as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7} from "./context.module.js";
|
||||
+import {useLocalizedStringDictionary as $fca6afa0e843324b$export$87b761675e8eaa10, useLocalizedStringFormatter as $fca6afa0e843324b$export$f12b703ca79dfbb1} from "./useLocalizedStringFormatter.module.js";
|
||||
+import {useNumberFormatter as $a916eb452884faea$export$b7a616150fdb9f44} from "./useNumberFormatter.module.js";
|
||||
+import {useCollator as $325a3faab7a68acd$export$a16aca283550c30d} from "./useCollator.module.js";
|
||||
+import {useFilter as $bb77f239b46e8c72$export$3274cf84b703fff} from "./useFilter.module.js";
|
||||
+// Slim barrel: removed useDateFormatter (@internationalized/date ~40KB) and useMessageFormatter (@formatjs ~62KB)
|
||||
+export {$18f2051aff69b9bf$export$a54013f0d02a8f82 as I18nProvider, $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 as useLocale, $fca6afa0e843324b$export$f12b703ca79dfbb1 as useLocalizedStringFormatter, $fca6afa0e843324b$export$87b761675e8eaa10 as useLocalizedStringDictionary, $a916eb452884faea$export$b7a616150fdb9f44 as useNumberFormatter, $325a3faab7a68acd$export$a16aca283550c30d as useCollator, $bb77f239b46e8c72$export$3274cf84b703fff as useFilter};
|
||||
diff --git a/dist/main.js b/dist/main.js
|
||||
index 62b1f5e2054df93a1f3e851f191c42441cf33699..820e10e6bf275b396a46e26a8e80f46b59bffb5c 100644
|
||||
--- a/dist/main.js
|
||||
+++ b/dist/main.js
|
||||
@@ -1,45 +1,13 @@
|
||||
var $47fa5ec5ff482271$exports = require("./context.main.js");
|
||||
-var $c376aa482226bf60$exports = require("./useMessageFormatter.main.js");
|
||||
-var $fc53663969a3d00a$exports = require("./useLocalizedStringFormatter.main.js");
|
||||
-var $cb6a3e7d490e97a4$exports = require("./useListFormatter.main.js");
|
||||
-var $b80c530ff2e20243$exports = require("./useDateFormatter.main.js");
|
||||
-var $fea93c5b7c90d9f4$exports = require("./useNumberFormatter.main.js");
|
||||
-var $27a5ce66022270ad$exports = require("./useCollator.main.js");
|
||||
-var $832d079b867c7223$exports = require("./useFilter.main.js");
|
||||
-
|
||||
-
|
||||
-function $parcel$export(e, n, v, s) {
|
||||
- Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
||||
-}
|
||||
-
|
||||
-$parcel$export(module.exports, "I18nProvider", () => $47fa5ec5ff482271$exports.I18nProvider);
|
||||
-$parcel$export(module.exports, "useLocale", () => $47fa5ec5ff482271$exports.useLocale);
|
||||
-$parcel$export(module.exports, "useMessageFormatter", () => $c376aa482226bf60$exports.useMessageFormatter);
|
||||
-$parcel$export(module.exports, "useLocalizedStringFormatter", () => $fc53663969a3d00a$exports.useLocalizedStringFormatter);
|
||||
-$parcel$export(module.exports, "useLocalizedStringDictionary", () => $fc53663969a3d00a$exports.useLocalizedStringDictionary);
|
||||
-$parcel$export(module.exports, "useListFormatter", () => $cb6a3e7d490e97a4$exports.useListFormatter);
|
||||
-$parcel$export(module.exports, "useDateFormatter", () => $b80c530ff2e20243$exports.useDateFormatter);
|
||||
-$parcel$export(module.exports, "useNumberFormatter", () => $fea93c5b7c90d9f4$exports.useNumberFormatter);
|
||||
-$parcel$export(module.exports, "useCollator", () => $27a5ce66022270ad$exports.useCollator);
|
||||
-$parcel$export(module.exports, "useFilter", () => $832d079b867c7223$exports.useFilter);
|
||||
-/*
|
||||
- * Copyright 2020 Adobe. All rights reserved.
|
||||
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
- * you may not use this file except in compliance with the License. You may obtain a copy
|
||||
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
- *
|
||||
- * Unless required by applicable law or agreed to in writing, software distributed under
|
||||
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
- * OF ANY KIND, either express or implied. See the License for the specific language
|
||||
- * governing permissions and limitations under the License.
|
||||
- */
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-//# sourceMappingURL=main.js.map
|
||||
+var $fc53663969a3d00a$exports = require("./useLocalizedStringFormatter.main.js");
|
||||
+var $8c5e0e4c6ca34e89$exports = require("./useNumberFormatter.main.js");
|
||||
+var $22f23e74d8a5e30d$exports = require("./useCollator.main.js");
|
||||
+var $7d0e351af20babe4$exports = require("./useFilter.main.js");
|
||||
+// Slim barrel: removed useDateFormatter, useMessageFormatter, useListFormatter
|
||||
+exports.I18nProvider = $47fa5ec5ff482271$exports.I18nProvider;
|
||||
+exports.useLocale = $47fa5ec5ff482271$exports.useLocale;
|
||||
+exports.useLocalizedStringFormatter = $fc53663969a3d00a$exports.useLocalizedStringFormatter;
|
||||
+exports.useLocalizedStringDictionary = $fc53663969a3d00a$exports.useLocalizedStringDictionary;
|
||||
+exports.useNumberFormatter = $8c5e0e4c6ca34e89$exports.useNumberFormatter;
|
||||
+exports.useCollator = $22f23e74d8a5e30d$exports.useCollator;
|
||||
+exports.useFilter = $7d0e351af20babe4$exports.useFilter;
|
||||
diff --git a/dist/module.js b/dist/module.js
|
||||
index fb8c9b0ce2c72d49866c95c3fd6e73cd26149775..6b6dc85b39196597504df1a287495a24ce3c0831 100644
|
||||
--- a/dist/module.js
|
||||
+++ b/dist/module.js
|
||||
@@ -1,31 +1,7 @@
|
||||
import {I18nProvider as $18f2051aff69b9bf$export$a54013f0d02a8f82, useLocale as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7} from "./context.module.js";
|
||||
-import {useMessageFormatter as $321bc95feeb923dd$export$ec23bf898b1eed85} from "./useMessageFormatter.module.js";
|
||||
-import {useLocalizedStringDictionary as $fca6afa0e843324b$export$87b761675e8eaa10, useLocalizedStringFormatter as $fca6afa0e843324b$export$f12b703ca79dfbb1} from "./useLocalizedStringFormatter.module.js";
|
||||
-import {useListFormatter as $33bf17300c498528$export$a2f47a3d2973640} from "./useListFormatter.module.js";
|
||||
-import {useDateFormatter as $896ba0a80a8f4d36$export$85fd5fdf27bacc79} from "./useDateFormatter.module.js";
|
||||
+import {useLocalizedStringDictionary as $fca6afa0e843324b$export$87b761675e8eaa10, useLocalizedStringFormatter as $fca6afa0e843324b$export$f12b703ca79dfbb1} from "./useLocalizedStringFormatter.module.js";
|
||||
import {useNumberFormatter as $a916eb452884faea$export$b7a616150fdb9f44} from "./useNumberFormatter.module.js";
|
||||
import {useCollator as $325a3faab7a68acd$export$a16aca283550c30d} from "./useCollator.module.js";
|
||||
import {useFilter as $bb77f239b46e8c72$export$3274cf84b703fff} from "./useFilter.module.js";
|
||||
-
|
||||
-/*
|
||||
- * Copyright 2020 Adobe. All rights reserved.
|
||||
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
||||
- * you may not use this file except in compliance with the License. You may obtain a copy
|
||||
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
- *
|
||||
- * Unless required by applicable law or agreed to in writing, software distributed under
|
||||
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
||||
- * OF ANY KIND, either express or implied. See the License for the specific language
|
||||
- * governing permissions and limitations under the License.
|
||||
- */
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
-export {$18f2051aff69b9bf$export$a54013f0d02a8f82 as I18nProvider, $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 as useLocale, $321bc95feeb923dd$export$ec23bf898b1eed85 as useMessageFormatter, $fca6afa0e843324b$export$f12b703ca79dfbb1 as useLocalizedStringFormatter, $fca6afa0e843324b$export$87b761675e8eaa10 as useLocalizedStringDictionary, $33bf17300c498528$export$a2f47a3d2973640 as useListFormatter, $896ba0a80a8f4d36$export$85fd5fdf27bacc79 as useDateFormatter, $a916eb452884faea$export$b7a616150fdb9f44 as useNumberFormatter, $325a3faab7a68acd$export$a16aca283550c30d as useCollator, $bb77f239b46e8c72$export$3274cf84b703fff as useFilter};
|
||||
-//# sourceMappingURL=module.js.map
|
||||
+// Slim barrel: removed useDateFormatter (@internationalized/date ~40KB) and useMessageFormatter (@formatjs ~62KB)
|
||||
+export {$18f2051aff69b9bf$export$a54013f0d02a8f82 as I18nProvider, $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 as useLocale, $fca6afa0e843324b$export$f12b703ca79dfbb1 as useLocalizedStringFormatter, $fca6afa0e843324b$export$87b761675e8eaa10 as useLocalizedStringDictionary, $a916eb452884faea$export$b7a616150fdb9f44 as useNumberFormatter, $325a3faab7a68acd$export$a16aca283550c30d as useCollator, $bb77f239b46e8c72$export$3274cf84b703fff as useFilter};
|
||||
24
.yarn/patches/@react-pdf-layout-npm-4.6.1-b12fdb71f4.patch
Normal file
24
.yarn/patches/@react-pdf-layout-npm-4.6.1-b12fdb71f4.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
diff --git a/lib/index.js b/lib/index.js
|
||||
index b7ea5e30fddb9bdef0034c00f28bbd4f0dee584a..47f7717632bd55d3c42ebb39f1ef5a23c14cfa3a 100644
|
||||
--- a/lib/index.js
|
||||
+++ b/lib/index.js
|
||||
@@ -2,8 +2,8 @@ import { upperFirst, capitalize, parseFloat as parseFloat$1, without, pick, comp
|
||||
import * as P from '@react-pdf/primitives';
|
||||
import resolveStyle, { transformColor, flatten } from '@react-pdf/stylesheet';
|
||||
import layoutEngine, { fontSubstitution, wordHyphenation, scriptItemizer, textDecoration, justification, linebreaker, bidi, fromFragments } from '@react-pdf/textkit';
|
||||
-import * as Yoga from 'yoga-layout/load';
|
||||
-import { loadYoga as loadYoga$1 } from 'yoga-layout/load';
|
||||
+import * as Yoga from 'yoga-layout/dist/src/load.js';
|
||||
+import { loadYoga as loadYoga$1 } from 'yoga-layout/dist/src/load.js';
|
||||
import emojiRegex from 'emoji-regex-xs';
|
||||
import resolveImage from '@react-pdf/image';
|
||||
|
||||
@@ -2998,7 +2998,7 @@ const splitPage = (page, pageNumber, fontStore, yoga) => {
|
||||
const dynamicPage = resolveDynamicPage({ pageNumber }, page, fontStore, yoga);
|
||||
const height = page.style.height;
|
||||
const [currentChilds, nextChilds] = splitNodes(wrapArea, contentArea, dynamicPage.children);
|
||||
- const relayout = (node) =>
|
||||
+ const relayout = (node) =>
|
||||
// @ts-expect-error rework pagination
|
||||
relayoutPage(node, fontStore, yoga);
|
||||
const currentBox = { ...page.box, height };
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user