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:
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
|
||||
Reference in New Issue
Block a user