Skip to content

Scoped PATs: permission enforcement #10944

Scoped PATs: permission enforcement

Scoped PATs: permission enforcement #10944

Workflow file for this run

name: Tests
on:
push:
branches:
- main
- maintenance
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check-changes:
name: Verify changes
runs-on: ubuntu-latest
outputs:
run_backend_tests: ${{ steps.changed-files.outputs.backend_changed }}
run_postgres_tests: ${{ steps.changed-files.outputs.postgres_changed }}
run_ui_tests: ${{ steps.changed-files.outputs.ui_changed }}
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Find changed files
id: changed-files
run: |
./.github/scripts/detect_changed_files.sh
check-ts-drift:
name: Check TypeScript drift
runs-on: ubuntu-latest
needs: check-changes
if: |
needs.check-changes.outputs.run_backend_tests == 'true' ||
needs.check-changes.outputs.run_postgres_tests == 'true' ||
needs.check-changes.outputs.run_ui_tests == 'true'
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Use Node.js 24
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
- name: Install Dependencies
run: npm ci
- name: Build the forge
run: npm run build
- name: Generate TypeScript types
run: npm run generate:types
env:
DEV_ENTERPRISE_TIER_LICENSE: ${{ secrets.DEV_ENTERPRISE_TIER_LICENSE }}
- name: Check drift
run: |
if ! git diff --exit-code frontend/src/types/generated.ts ; then
echo ""
echo "::error::Type drift detected! Run 'npm run generate:types' locally and commit the result."
exit 1
fi
backend-tests:
if: ${{ needs.check-changes.outputs.run_backend_tests == 'true' }}
name: Backend tests
needs:
- check-changes
- check-ts-drift
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Use Node.js 24
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
- name: Install Dependencies
run: npm ci
- name: Build the forge
run: npm run build
- name: Run forge unit tests
run: npm run cover:unit:forge
- name: Run forge system tests
run: npm run cover:system
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
flags: backend
postgres-tests:
if: ${{ needs.check-changes.outputs.run_postgres_tests == 'true' }}
name: Postgres tests
needs:
- check-changes
- check-ts-drift
runs-on: ubuntu-latest
timeout-minutes: 45
services:
postgres:
image: postgres:14
env:
POSTGRES_PASSWORD: secret
POSTGRES_USER: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
-m 3GB
ports:
- 5432:5432
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup NodeJS 24
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
- name: Install Dependencies
run: npm ci
- name: Build the forge
run: npm run build
- name: Test the forge (with PostgreSQL)
env:
FF_TEST_DB_POSTGRES: true
FF_TEST_DB_POSTGRES_HOST: localhost
FF_TEST_DB_POSTGRES_PORT: 5432
FF_TEST_DB_POSTGRES_USER: postgres
FF_TEST_DB_POSTGRES_PASSWORD: secret
FF_TEST_DB_POSTGRES_DATABASE: flowforge
NODE_OPTIONS: "--max-old-space-size=6144"
run: npm run test
ui-unit-tests:
if: ${{ needs.check-changes.outputs.run_ui_tests == 'true' }}
name: UI unit tests
needs:
- check-changes
- check-ts-drift
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Dependencies
run: npm ci
- name: Run Linting Tests
run: npm run lint
- name: Run UI Unit Tests
run: npm run test:unit:frontend
ui-os-tests:
if: ${{ needs.check-changes.outputs.run_ui_tests == 'true' }}
name: UI OS tests
needs:
- check-changes
- check-ts-drift
runs-on: ubuntu-latest
services:
email-service:
image: axllent/mailpit
ports:
- 8025:8025
- 1025:1025
options: >-
--env MP_MAX_MESSAGES=5000
--env MP_SMTP_AUTH_ACCEPT_ANY=1
--env MP_SMTP_AUTH_ALLOW_INSECURE=1
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Dependencies
run: npm ci
- name: Run UI E2E (Cypress) Tests - OS
uses: cypress-io/github-action@948d67d3074f1bbb6379c8bdbb04e95d2f8e593f # v7.4.0
with:
install: false
config-file: config/cypress-os.config.js
build: npm run build
start: npm run cy:web-server:os
env:
NO_SMTP_SERVER: 'true'
SMTP_HOST: 'localhost'
SMTP_PORT: '1025'
SMTP_WEB_PORT: '8025'
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: failure()
with:
name: os-cypress-output-${{ github.run_id }}-${{ github.run_number }}
path: |
test/e2e/frontend/cypress/screenshots
test/e2e/frontend/cypress/videos
ui-ee-tests:
if: ${{ needs.check-changes.outputs.run_ui_tests == 'true' }}
name: UI EE tests
needs:
- check-changes
- check-ts-drift
runs-on: ubuntu-latest
services:
email-service:
image: axllent/mailpit
ports:
- 8025:8025
- 1025:1025
options: >-
--env MP_MAX_MESSAGES=5000
--env MP_SMTP_AUTH_ACCEPT_ANY=1
--env MP_SMTP_AUTH_ALLOW_INSECURE=1
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install Dependencies
run: npm ci
- name: Run UI E2E (Cypress) Tests - EE
uses: cypress-io/github-action@948d67d3074f1bbb6379c8bdbb04e95d2f8e593f # v7.4.0
with:
install: false
config-file: config/cypress-ee.config.js
build: npm run build
start: npm run cy:web-server:ee
env:
NO_SMTP_SERVER: 'true'
SMTP_HOST: 'localhost'
SMTP_PORT: '1025'
SMTP_WEB_PORT: '8025'
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: failure()
with:
name: ee-cypress-output-${{ github.run_id }}-${{ github.run_number }}
path: |
test/e2e/frontend/cypress/screenshots
test/e2e/frontend/cypress/videos
### We use this job to gather results from all test jobs and determine the final status of the tests execution.
### Jobs executed with the matrix strategy have dynamic names and cannot be referenced in the status checks of the pull request.
tests-summary:
name: Tests summary
if: ${{ always() }}
needs:
- check-changes
- check-ts-drift
- backend-tests
- postgres-tests
- ui-unit-tests
- ui-os-tests
- ui-ee-tests
runs-on: ubuntu-latest
steps:
- name: Evaluate test job results
run: |
results=(
'${{ needs.check-ts-drift.result }}'
'${{ needs.backend-tests.result }}'
'${{ needs.postgres-tests.result }}'
'${{ needs.ui-unit-tests.result }}'
'${{ needs.ui-os-tests.result }}'
'${{ needs.ui-ee-tests.result }}'
)
echo 'Test job results:'
printf '%s\n' "${results[@]}"
for result in "${results[@]}"; do
if [ "$result" = 'failure' ] || [ "$result" = 'cancelled' ]; then
echo 'One or more test jobs failed or were cancelled'
exit 1
fi
done
echo 'All test jobs succeeded or were skipped'
notify-slack:
name: Notify on failure
needs: tests-summary
if: failure()
runs-on: ubuntu-latest
steps:
- name: Notify Slack
uses: FlowFuse/github-actions-workflows/actions/slack_notification@slack_notification/v1
with:
bot-token: ${{ secrets.SLACK_GHBOT_TOKEN }}
mode: ${{ github.event_name == 'pull_request' && 'author' || 'channel' }}
mention-actor: ${{ github.event_name != 'pull_request' }}
blocks: |
[
{ "type": "header", "text": { "type": "plain_text", "text": ":x: ${{ github.event_name == 'pull_request' && format('Tests failed against {0} pull request', github.event.pull_request.number) || format('Tests failed against {0} branch', github.ref_name) }}", "emoji": true } },
{ "type": "divider" },
{ "type": "rich_text", "elements": [ { "type": "rich_text_section", "elements": [
{ "type": "emoji", "name": "${{ github.event_name == 'pull_request' && 'warning' || 'no_entry' }}" },
{ "type": "text", "text": "${{ github.event_name == 'pull_request' && ' Please resolve the problem before merging your changes into the main branch.' || ' Deployment to FFC environments will not happen until this issue is resolved.' }}", "style": { "bold": true } }
] } ] },
{ "type": "divider" },
{ "type": "section", "fields": [
{ "type": "mrkdwn", "text": "*Author:* ${{ github.event_name == 'pull_request' && github.actor || '{{MENTION}}' }}" },
{ "type": "mrkdwn", "text": "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View failed workflow>" },
{ "type": "mrkdwn", "text": "${{ format('*Last commit:* <{0}/{1}/commit/{2}|{2}>', github.server_url, github.repository, github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha) }}" },
{ "type": "mrkdwn", "text": "${{ github.event_name == 'pull_request' && format('*Pull request:* <{0}/{1}/pull/{2}|{2}>', github.server_url, github.repository, github.event.pull_request.number) || format('*Branch:* {0}', github.ref_name) }}" }
] }
]