Skip to content

fix(bff): cap page.limit and rate-limit agent requests #10129

fix(bff): cap page.limit and rate-limit agent requests

fix(bff): cap page.limit and rate-limit agent requests #10129

Workflow file for this run

name: Lint, Build, Test and Doc
on:
push:
branches:
- main
- alpha
- "alpha-*"
- beta
- "beta-*"
pull_request:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
name: Installing & Building
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]')"
steps:
- name: Cancel previous running workflows
uses: fkirc/skip-duplicate-actions@master
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- uses: actions/cache@v4
with:
path: |
node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/*/package.json') }}
- name: Install & Bootstrap
run: yarn && yarn bootstrap --ci
- name: Build
run: yarn build
- uses: actions/cache/save@v4
with:
path: packages/*/dist
key: ${{ runner.os }}-build-${{ github.sha }}
lint:
name: Lint commit messages
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Lint commit message
uses: wagoid/commitlint-github-action@v5
test:
name: Linting & Testing
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [build]
strategy:
matrix:
package:
- agent
- agent-bff
- agent-client
- agent-testing
- agent-toolkit
- ai-proxy
- forest-cloud
- mcp-server
- datasource-customizer
- datasource-demo-fintech
- datasource-dummy
- datasource-mongoose
- datasource-replica
- datasource-mongo
- datasource-sequelize
- datasource-sql
- datasource-toolkit
- forestadmin-client
- plugin-aws-s3
- plugin-export-advanced
- plugin-flattener
- workflow-executor
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Start docker containers
if: ${{ matrix.package == 'datasource-mongo' || matrix.package == 'datasource-mongoose' || matrix.package == 'datasource-sql' || matrix.package == 'datasource-sequelize' }}
run: docker compose -f ./packages/${{ matrix.package }}/docker-compose.yml up -d; sleep 5
- name: Restore dependencies from cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/*/package.json') }}
fail-on-cache-miss: true
- name: Restore build from cache
uses: actions/cache/restore@v4
with:
path: packages/*/dist
key: ${{ runner.os }}-build-${{ github.sha }}
fail-on-cache-miss: true
- name: Lint Typescript
run: cd packages/${{ matrix.package }} && yarn lint && cd -
# The ignore list names each integration suite explicitly rather than matching `integration`
# broadly: most packages keep genuine unit tests under `test/integration*/`, and a wide
# pattern would silently stop running hundreds of them.
- name: Test code (excluding integration suites with their own job)
run: cd packages/${{ matrix.package }} && yarn test --coverage --testPathIgnorePatterns='llm.integration|search-agent.integration' && cd -
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.package }}
path: packages/${{ matrix.package }}/coverage/clover.xml
retention-days: 1
llm-integration-tests:
name: LLM Integration Tests (ai-proxy)
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [build]
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Restore dependencies from cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/*/package.json') }}
fail-on-cache-miss: true
- name: Restore build from cache
uses: actions/cache/restore@v4
with:
path: packages/*/dist
key: ${{ runner.os }}-build-${{ github.sha }}
fail-on-cache-miss: true
- name: Run LLM integration tests
run: yarn workspace @forestadmin/ai-proxy test --testPathPattern='llm.integration'
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# Boots a real agent on a local HTTP port, so it stays out of the unit job. Unlike the LLM suite
# it reaches no third party and is deterministic, hence no continue-on-error: it must gate.
bff-integration-tests:
name: BFF Integration Tests (agent-bff)
runs-on: ubuntu-latest
timeout-minutes: 15
needs: [build]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Restore dependencies from cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/*/package.json') }}
fail-on-cache-miss: true
- name: Restore build from cache
uses: actions/cache/restore@v4
with:
path: packages/*/dist
key: ${{ runner.os }}-build-${{ github.sha }}
fail-on-cache-miss: true
- name: Run BFF integration tests
run: yarn workspace @forestadmin/agent-bff test --testPathPattern='search-agent.integration'
send-coverage:
name: Send Coverage
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [test]
steps:
- uses: actions/checkout@v4
- name: Download coverage reports
uses: actions/download-artifact@v4
with:
path: reports
- name: Send coverage
uses: qltysh/qlty-action/coverage@8d5c844f32f80364ccc135534671640466e7f610 #v1.1
with:
oidc: true
files: |
${{github.workspace}}/reports/**/clover.xml
build-api-reference:
name: Build API Reference
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Restore dependencies from cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/*/package.json') }}
fail-on-cache-miss: true
- name: Restore build from cache
uses: actions/cache/restore@v4
with:
path: packages/*/dist
key: ${{ runner.os }}-build-${{ github.sha }}
fail-on-cache-miss: true
- name: Build doc
run: yarn docs
- name: Archive documentation artifacts
uses: actions/upload-pages-artifact@v3
with:
path: api-reference
release:
name: Release packages
runs-on: ubuntu-latest
# Serialize releases per branch so concurrent merges can't run multi-semantic-release
# in parallel: an overlapping run sees the branch as "behind remote" and silently skips
# publishing. cancel-in-progress must stay false β€” a release must never be interrupted
# mid-publish. The tip run (github.sha == branch head, matching the sha-keyed dist cache)
# then drains the whole pending backlog.
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
needs: [build-api-reference, send-coverage, lint, bff-integration-tests]
if: |
github.event_name == 'push'
&& (
github.ref == 'refs/heads/main'
|| github.ref == 'refs/heads/beta'
|| github.ref == 'refs/heads/alpha'
|| startsWith(github.ref, 'refs/heads/alpha-')
|| startsWith(github.ref, 'refs/heads/beta-')
)
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false # GITHUB_TOKEN must not be set for the semantic release
- uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
- name: Restore dependencies from cache
uses: actions/cache/restore@v4
with:
path: |
node_modules
packages/*/node_modules
key: ${{ runner.os }}-modules-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/*/package.json') }}
fail-on-cache-miss: true
- name: Install npm >= 11.15.0
run: npm install -g 'npm@^11'
- name: Restore build from cache
uses: actions/cache/restore@v4
with:
path: packages/*/dist
key: ${{ runner.os }}-build-${{ github.sha }}
fail-on-cache-miss: true
- name: Disable workspaces-update
run: npm config set workspaces-update false
- name: Snapshot workflow-executor tags (pre-release)
run: git tag --list '@forestadmin/workflow-executor@*' | sort > /tmp/we-tags-before.txt
- name: "Run multi-semantic-release"
run: "$(yarn bin)/multi-semantic-release --deps.bump=override"
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
GIT_COMMITTER_EMAIL: ${{ secrets.GIT_COMMITTER_EMAIL }}
GIT_COMMITTER_NAME: ${{ secrets.GIT_COMMITTER_NAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
NPM_CONFIG_PROVENANCE: true
# The tag-push trigger can't build the image: the release commit carries
# `[skip ci]`, which GitHub honors on tag pushes too. Dispatch explicitly.
# Runs even on a failed release: tags/npm are published partway, so a new
# tag still means the image must be built to match. The snapshot guard below
# skips the case where the release step never ran (failure before it).
- name: Trigger workflow-executor Docker image publish (if released)
if: ${{ !cancelled() }}
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
if [ ! -f /tmp/we-tags-before.txt ]; then
echo "Pre-release snapshot missing β€” release step never ran; nothing to publish."
exit 0
fi
git tag --list '@forestadmin/workflow-executor@*' | sort > /tmp/we-tags-after.txt
NEW_TAGS=$(comm -13 /tmp/we-tags-before.txt /tmp/we-tags-after.txt)
if [ -z "$NEW_TAGS" ]; then
echo "No new @forestadmin/workflow-executor tag in this run β€” nothing to publish."
exit 0
fi
# If more than one appears, pick the highest so :latest never regresses.
VERSION=$(echo "$NEW_TAGS" \
| sed 's|^@forestadmin/workflow-executor@||' \
| sort -V | tail -n1)
echo "workflow-executor@${VERSION} released β€” dispatching docker-publish.yml."
gh workflow run docker-publish.yml --ref "$GITHUB_REF_NAME" -f version="$VERSION"
publish-api-reference:
name: Publish API Reference
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [build-api-reference, send-coverage, lint, bff-integration-tests]
steps:
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4