|
35798
|
24524
|
76
|
5
|
00fad17f6b0dc914bc2382e9628907a656f67c86
|
0
|
Static governance
|
0
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1790291379
|
1790291118
|
1790291379
|
|
0
|
|
0
|
Edit
Delete
|
|
35816
|
24526
|
76
|
5
|
4a4c3e77cc30429ccc00f274c19e073053f52f73
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30403
|
2
|
1790292143
|
1790292173
|
1790291379
|
1790292174
|
|
0
|
|
0
|
Edit
Delete
|
|
35910
|
24541
|
76
|
5
|
0ec1ffec8962590df5d7d130b04c445815f86a15
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30441
|
2
|
1790296036
|
1790296046
|
1790295992
|
1790296046
|
|
0
|
|
0
|
Edit
Delete
|
|
35928
|
24543
|
76
|
5
|
b26d51b926223ee7c225026b86701bf5121b2e04
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30451
|
2
|
1790297007
|
1790297097
|
1790297007
|
1790297098
|
|
0
|
|
0
|
Edit
Delete
|
|
36108
|
24567
|
54
|
5
|
4a0e14fbf457395bb2086641776559d16ca88c5f
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: "20"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
- if: always()
name: Upload immutable static governance evidence
uses: actions/upload-artifact@v4
with:
if-no-files-found: warn
name: governance-${{ github.job }}-${{ github.sha }}-${{ github.run_attempt }}
path: |
reports/*.latest.json
!reports/governance-profile-*.latest.json
!reports/runtime-acceptance.latest.json
!reports/conformance-differential.latest.json
!reports/ui-acceptance.latest.json
retention-days: "30"
timeout-minutes: "20"
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30574
|
2
|
1790403758
|
1790403848
|
1790403757
|
1790403849
|
|
0
|
|
0
|
Edit
Delete
|
|
36111
|
24568
|
54
|
5
|
60c6b05660880e31da756180599fbe008ee73f8d
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: "20"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
- if: always()
name: Upload immutable static governance evidence
uses: actions/upload-artifact@v4
with:
if-no-files-found: warn
name: governance-${{ github.job }}-${{ github.sha }}-${{ github.run_attempt }}
path: |
reports/*.latest.json
!reports/governance-profile-*.latest.json
!reports/runtime-acceptance.latest.json
!reports/conformance-differential.latest.json
!reports/ui-acceptance.latest.json
retention-days: "30"
timeout-minutes: "20"
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30576
|
2
|
1790403912
|
1790404953
|
1790403783
|
1790404953
|
|
1
|
|
0
|
Edit
Delete
|
|
36157
|
24584
|
54
|
5
|
b3b776d50fd8c6aba1c699cb4497aa22efbad8e0
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: "20"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
- if: always()
name: Upload immutable static governance evidence
uses: actions/upload-artifact@v4
with:
if-no-files-found: warn
name: governance-${{ github.job }}-${{ github.sha }}-${{ github.run_attempt }}
path: |
reports/*.latest.json
!reports/governance-profile-*.latest.json
!reports/runtime-acceptance.latest.json
!reports/conformance-differential.latest.json
!reports/ui-acceptance.latest.json
retention-days: "30"
timeout-minutes: "20"
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30615
|
2
|
1790420491
|
1790420540
|
1790420050
|
1790420541
|
|
0
|
|
0
|
Edit
Delete
|
|
36196
|
24593
|
83
|
5
|
849a0460c229611a1afa4b798be51fbc72408273
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30647
|
2
|
1790427960
|
1790428018
|
1790427902
|
1790428018
|
|
0
|
|
0
|
Edit
Delete
|
|
36229
|
24603
|
83
|
5
|
890186f6ced6dcb9f3ed0cf8181953c468022255
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30685
|
2
|
1790432775
|
1790432833
|
1790432773
|
1790432833
|
|
0
|
|
0
|
Edit
Delete
|
|
36242
|
24607
|
76
|
5
|
ba2eb4b48ece4515f3e5ed5cd01b4988ef9476f0
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30697
|
2
|
1790462249
|
1790462259
|
1790462249
|
1790462260
|
|
0
|
|
0
|
Edit
Delete
|
|
36269
|
24611
|
83
|
5
|
3744c329b0b337a61367a86167e3ddf2a878f373
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30710
|
2
|
1790463385
|
1790463442
|
1790463384
|
1790463442
|
|
0
|
|
0
|
Edit
Delete
|
|
36276
|
24616
|
76
|
5
|
d7c7cd6e7d0f2f5c74b5f851fe0e93f2e4daf445
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30716
|
2
|
1790464840
|
1790464849
|
1790464840
|
1790464850
|
|
0
|
|
0
|
Edit
Delete
|
|
36294
|
24618
|
83
|
5
|
67811861157d0cc927d11306ab6118f0518e0e96
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30720
|
2
|
1790465298
|
1790465356
|
1790465297
|
1790465356
|
|
0
|
|
0
|
Edit
Delete
|
|
36299
|
24621
|
76
|
5
|
9211af176582cf84be7953284ebaaa8585415582
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30724
|
2
|
1790466844
|
1790466934
|
1790466842
|
1790466934
|
|
0
|
|
0
|
Edit
Delete
|
|
36317
|
24623
|
83
|
5
|
f8aa03f477027c619e28ce7ac4ddceb99419366b
|
0
|
Static governance
|
0
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1790467738
|
1790467281
|
1790467738
|
|
0
|
|
0
|
Edit
Delete
|
|
36321
|
24625
|
83
|
5
|
9bd8501f3ca5b64c3cb2ec68dd04606cd859d526
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30728
|
2
|
1790468029
|
1790468059
|
1790467738
|
1790468060
|
|
0
|
|
0
|
Edit
Delete
|
|
36361
|
24635
|
76
|
5
|
bf3489874b13f86fd2a36d382c4bbf7fc6adcddd
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30755
|
2
|
1790471641
|
1790471650
|
1790471202
|
1790471650
|
|
0
|
|
0
|
Edit
Delete
|
|
36379
|
24637
|
76
|
5
|
df2aef526eda9ed1dc816004cde4d617e5e0c1dd
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020
with:
node-version: 22.23.2
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.GITEA_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
- name: Rebuild approved dependency scripts
run: pnpm dependencies:rebuild-approved
- name: Audit production dependencies
run: pnpm audit --prod --audit-level high
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
permissions:
contents: read
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30759
|
2
|
1790475590
|
1790475681
|
1790475589
|
1790475681
|
|
0
|
|
0
|
Edit
Delete
|
|
36397
|
24639
|
83
|
5
|
5df3d8bdb23929348dd87a448e74eb442a290414
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30763
|
2
|
1790476600
|
1790476658
|
1790476598
|
1790476658
|
|
0
|
|
0
|
Edit
Delete
|
|
36401
|
24641
|
83
|
5
|
0bfbacf591e40a08a4b1ec032491c0ab2c31e3e3
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30766
|
2
|
1790477536
|
1790477597
|
1790477536
|
1790477597
|
|
0
|
|
0
|
Edit
Delete
|
|
36405
|
24643
|
83
|
5
|
14861eb6af3192643ae427d3a11efa6d0ce702db
|
0
|
Static governance
|
1
|
name: Governance
"on":
pull_request:
name: Governance
"on":
pull_request:
push:
branches:
- main
jobs:
static-governance:
name: Static governance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Enable pnpm
run: |
corepack enable
corepack prepare pnpm@9.15.9 --activate
- if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
name: Configure read-only platform package authentication
run: node scripts/configure-platform-npm.mjs
env:
PLATFORM_NPM_TOKEN: ${{ secrets.PLATFORM_NPM_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate Prisma clients
run: pnpm prisma:generate
- name: Run static governance gate
run: pnpm check
...
|
static-governance
|
null
|
["ubuntu-latest"]
|
30769
|
2
|
1790477885
|
1790477975
|
1790477883
|
1790477975
|
|
0
|
|
0
|
Edit
Delete
|
|
9066
|
7307
|
6
|
5
|
339ea969ec2633756fb1a155d47723d0f61396a4
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
7838
|
2
|
1774231378
|
1774231400
|
1774231240
|
1774231400
|
|
1
|
|
0
|
Edit
Delete
|
|
12936
|
9521
|
6
|
5
|
58e5152a38868b8f3832d9573c340a3eb60051c8
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
10934
|
2
|
1774836525
|
1774836934
|
1774836018
|
1774836934
|
|
1
|
|
0
|
Edit
Delete
|
|
16459
|
11697
|
6
|
5
|
9d69e1960ec649a49c0c6f307c0fc197f47ee4c4
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
13753
|
2
|
1775441168
|
1775441259
|
1775440818
|
1775441259
|
|
1
|
|
0
|
Edit
Delete
|
|
18684
|
13739
|
6
|
5
|
98cc8da660b8d4dba9887432490471d976c03f5f
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
15923
|
2
|
1776046761
|
1776046852
|
1776045650
|
1776046852
|
|
1
|
|
0
|
Edit
Delete
|
|
21248
|
15824
|
6
|
5
|
7b47df3186db279cfc071517a6c034aa213d926d
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "18"
PNPM_VERSION: "8"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
18263
|
2
|
1776650711
|
1776650837
|
1776650450
|
1776650837
|
|
1
|
|
0
|
Edit
Delete
|
|
24017
|
17928
|
6
|
5
|
8b28a0af74c8801b122de4d42a95742e2302646a
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
20637
|
2
|
1777255378
|
1777255468
|
1777255250
|
1777255468
|
|
1
|
|
0
|
Edit
Delete
|
|
25572
|
18854
|
6
|
5
|
982b47544d9cefb513875cc84c6c36bf1ee27fb2
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
21923
|
4
|
1777522326
|
1777522326
|
1777515700
|
1777522326
|
|
1
|
|
0
|
Edit
Delete
|
|
25680
|
18900
|
6
|
5
|
00e6c41c98f5eca066cac8efd4dc9e91dfe5f583
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
22014
|
4
|
1777545499
|
1777545499
|
1777531657
|
1777545499
|
|
1
|
|
0
|
Edit
Delete
|
|
26000
|
19098
|
6
|
5
|
6845ebac54cb057c62116944a21c3a04b78708bf
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
22293
|
4
|
1777609470
|
1777609470
|
1777597570
|
1777609470
|
|
1
|
|
0
|
Edit
Delete
|
|
26920
|
19950
|
6
|
5
|
468c7319f39e251cdf8eb96c3aa63f4db200a7db
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
23197
|
2
|
1777860255
|
1777860401
|
1777860040
|
1777860401
|
|
1
|
|
0
|
Edit
Delete
|
|
29006
|
21981
|
6
|
5
|
468c7319f39e251cdf8eb96c3aa63f4db200a7db
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm --filter shared build
pnpm --filter backend build
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: postgres:15
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
25283
|
2
|
1778465155
|
1778465285
|
1778464840
|
1778465285
|
|
1
|
|
0
|
Edit
Delete
|
|
29936
|
22657
|
6
|
5
|
921a6ce5568beb3034fc47d4bf7a392351c0068f
|
0
|
💥 压力测试
|
1
|
name: Performance Tests
"on":
# 每周一凌晨 name: Performance Tests
"on":
# 每周一凌晨 2 点运行
schedule:
- cron: '0 2 * * 1'
# 允许手动触发
workflow_dispatch:
inputs:
test_type:
description: '测试类型'
required: true
default: 'benchmark'
type: choice
options:
- benchmark
- load
- stress
- all
duration:
description: '测试持续时间(秒)'
required: false
default: '60'
type: string
concurrency:
description: '并发数'
required: false
default: '10'
type: string
# PR 触发时只运行基准测试
pull_request:
branches: [main]
paths:
- 'backend/src/**'
- 'backend/prisma/**'
env:
NODE_OPTIONS: --max-old-space-size=8192
NODE_VERSION: "20"
PNPM_VERSION: "9"
jobs:
stress-test:
name: "\U0001F4A5 压力测试"
runs-on: ubuntu-latest
if: needs.setup.outputs.test_type == 'stress' || needs.setup.outputs.test_type == 'all'
steps:
- name: "\U0001F4E5 检出代码"
uses: actions/checkout@v4
- name: "\U0001F4E6 安装 pnpm"
uses: pnpm/action-setup@v4
- name: "\U0001F7E2 设置 Node.js"
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 安装依赖"
run: pnpm install --frozen-lockfile
- name: "\U0001F527 安装 k6"
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
- name: "\U0001F5C4️ 初始化数据库"
run: |
cd backend
npx prisma migrate deploy
npx prisma db seed
env:
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
DIRECT_URL: postgresql://test:test@localhost:5432/juhi_stress
- name: "\U0001F528 构建后端"
run: |
pnpm -C backend exec prisma generate --schema prisma/schema
pnpm -C shared run build
pnpm -C backend run build:fast
- name: "\U0001F680 启动后端服务"
run: |
cd backend
npm run start &
sleep 10
env:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://test:test@localhost:5432/juhi_stress
DIRECT_URL: postgresql://test:test@localhost:5432/juhi_stress
REDIS_URL: redis://localhost:6379
JWT_SECRET: stress-test-jwt-secret
REFRESH_TOKEN_SECRET: stress-test-refresh-token
- name: ⏳ 等待服务就绪
run: |
timeout 60 bash -c 'until curl -s http://localhost:3000/health > /dev/null; do sleep 2; done'
- name: "\U0001F4A5 运行压力测试"
run: |
mkdir -p stress-test-results
# 创建 k6 压力测试脚本
cat > stress-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
const requestCount = new Counter('requests');
export const options = {
stages: [
{ duration: '1m', target: 20 }, // 预热
{ duration: '2m', target: 100 }, // 逐步增加到 100 并发
{ duration: '2m', target: 200 }, // 增加到 200 并发
{ duration: '2m', target: 300 }, // 增加到 300 并发
{ duration: '1m', target: 0 }, // 降低
],
thresholds: {
http_req_duration: ['p(99)<2000'], // 99% 请求小于 2s
errors: ['rate<0.3'], // 错误率小于 30%
},
};
const BASE_URL = 'http://localhost:3000';
export default function () {
requestCount.add(1);
let res = http.get(`${BASE_URL}/health`);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 1000ms': (r) => r.timings.duration < 1000,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(0.05);
}
EOF
k6 run --out json=stress-test-results/results.json stress-test.js || true
- name: "\U0001F4CA 分析压力测试结果"
run: "echo \"## \U0001F4A5 压力测试报告\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\necho \"### 测试目标\" >> $GITHUB_STEP_SUMMARY\necho \"- 最大并发: 300\" >> $GITHUB_STEP_SUMMARY\necho \"- 持续时间: 8 分钟\" >> $GITHUB_STEP_SUMMARY\necho \"\" >> $GITHUB_STEP_SUMMARY\n\nif [ -f \"stress-test-results/results.json\" ]; then\n echo \"### 结果分析\" >> $GITHUB_STEP_SUMMARY\n\n max_vus=$(cat stress-test-results/results.json | jq -s 'max_by(.data.value | numbers) | .data.value // 0' 2>/dev/null || echo \"N/A\")\n echo \"- 最大达到 VUs: $max_vus\" >> $GITHUB_STEP_SUMMARY\nfi\n"
- name: "\U0001F4E4 上传压力测试结果"
uses: actions/upload-artifact@v4
with:
name: stress-test-results
path: stress-test-results/
retention-days: "30"
timeout-minutes: "60"
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_DB: juhi_stress
POSTGRES_PASSWORD: test
POSTGRES_USER: test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
redis:
image: redis:7
ports:
- 6379:6379
...
|
stress-test
|
["setup"]
|
["ubuntu-latest"]
|
26127
|
4
|
1778687827
|
1778687827
|
1778679719
|
1778687827
|
|
1
|
|
0
|
Edit
Delete
|
|
7831
|
6702
|
6
|
5
|
e112d45af414e4862c0328abad7c4df74d3c1dbf
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
6744
|
2
|
1773832182
|
1773832208
|
1773831748
|
1773832209
|
|
0
|
|
0
|
Edit
Delete
|
|
7857
|
6706
|
6
|
5
|
e112d45af414e4862c0328abad7c4df74d3c1dbf
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
6759
|
2
|
1773832621
|
1773832651
|
1773831750
|
1773832651
|
|
0
|
|
0
|
Edit
Delete
|
|
7893
|
6712
|
6
|
5
|
b7eb415d7a9689f1efec941bcb2dcd7d098e9c28
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
6772
|
2
|
1773832815
|
1773832838
|
1773832743
|
1773832838
|
|
0
|
|
0
|
Edit
Delete
|
|
7919
|
6716
|
6
|
5
|
b7eb415d7a9689f1efec941bcb2dcd7d098e9c28
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
6787
|
2
|
1773833170
|
1773833185
|
1773832746
|
1773833185
|
|
0
|
|
0
|
Edit
Delete
|
|
8148
|
6903
|
6
|
5
|
b7eb415d7a9689f1efec941bcb2dcd7d098e9c28
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7030
|
2
|
1773885615
|
1773885635
|
1773885613
|
1773885635
|
|
0
|
|
0
|
Edit
Delete
|
|
8282
|
6999
|
6
|
5
|
bd59e5501292cb061719f669c7a7b7afd4f1a0b7
|
0
|
🔒 多租户安全审计
|
0
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
0
|
3
|
0
|
1773913347
|
1773912914
|
1773913347
|
|
0
|
|
0
|
Edit
Delete
|
|
8340
|
7007
|
6
|
5
|
01a8ea9191c28b210d2abb3db3cbc65db42fc801
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7155
|
2
|
1773914068
|
1773914085
|
1773913348
|
1773914085
|
|
0
|
|
0
|
Edit
Delete
|
|
8449
|
7068
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7263
|
2
|
1773929449
|
1773929475
|
1773929407
|
1773929475
|
|
0
|
|
0
|
Edit
Delete
|
|
8475
|
7072
|
6
|
5
|
9771b23ae7aaee164f15f9c4ccbdb18eb68fc71f
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7278
|
2
|
1773929807
|
1773929822
|
1773929409
|
1773929822
|
|
0
|
|
0
|
Edit
Delete
|
|
8558
|
7113
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7362
|
2
|
1773939813
|
1773939835
|
1773939780
|
1773939835
|
|
0
|
|
0
|
Edit
Delete
|
|
8584
|
7117
|
6
|
5
|
979d9c81063fbda12f1445bf80b0c0027b0fbac2
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7377
|
2
|
1773940157
|
1773940171
|
1773939782
|
1773940171
|
|
0
|
|
0
|
Edit
Delete
|
|
8747
|
7231
|
6
|
5
|
0900b15d607e5c78f97fec16a73357ad4f814390
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7541
|
2
|
1774221023
|
1774221046
|
1774220984
|
1774221046
|
|
0
|
|
0
|
Edit
Delete
|
|
8773
|
7235
|
6
|
5
|
0900b15d607e5c78f97fec16a73357ad4f814390
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7556
|
2
|
1774221369
|
1774221383
|
1774220986
|
1774221384
|
|
0
|
|
0
|
Edit
Delete
|
|
8849
|
7252
|
6
|
5
|
80c2bdb2f93a19aa53d16ded06387b70c6084bf8
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7624
|
2
|
1774223303
|
1774223317
|
1774223021
|
1774223318
|
|
0
|
|
0
|
Edit
Delete
|
|
8920
|
7264
|
6
|
5
|
df7b6f46170cb46db4771dd1e07991b0b13d90a0
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7685
|
2
|
1774223798
|
1774223813
|
1774223518
|
1774223813
|
|
0
|
|
0
|
Edit
Delete
|
|
8998
|
7290
|
6
|
5
|
339ea969ec2633756fb1a155d47723d0f61396a4
|
0
|
🔒 多租户安全审计
|
1
|
name: Database Security Audit
"on":
pu name: Database Security Audit
"on":
push:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
pull_request:
branches: [main, develop]
paths:
- 'backend/src/**/*.ts'
- 'backend/prisma/**'
schedule:
# 每天凌晨 2 点执行完整审计
- cron: '0 2 * * *'
workflow_dispatch:
inputs:
full_audit:
description: '执行完整审计(包含 RLS 迁移建议)'
required: false
default: 'false'
type: boolean
env:
NODE_VERSION: "18"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- name: "\U0001F4E5 Checkout code"
uses: actions/checkout@v4
- name: "\U0001F7E2 Setup Node.js"
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: "\U0001F4E6 Setup pnpm"
uses: pnpm/action-setup@v2
with:
version: "8"
- name: "\U0001F4E5 Install dependencies"
run: pnpm install --frozen-lockfile
- id: tenant-audit
name: "\U0001F50D 多租户隔离检查"
run: |
cd backend
npm run audit:tenant 2>&1 | tee tenant-audit.log
# 检查是否有 P0 级别问题
if grep -q "P0" tenant-audit.log; then
echo "has_p0_issues=true" >> $GITHUB_OUTPUT
else
echo "has_p0_issues=false" >> $GITHUB_OUTPUT
fi
- name: "\U0001F4CA 上传审计报告"
uses: actions/upload-artifact@v4
with:
name: tenant-security-report
path: backend/tenant-audit.log
- if: steps.tenant-audit.outputs.has_p0_issues == 'true'
name: ❌ P0 问题阻断
run: |
echo "::error::发现 P0 级别多租户安全问题,禁止合并!"
exit 1
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7759
|
2
|
1774229096
|
1774229117
|
1774229062
|
1774229118
|
|
0
|
|
0
|
Edit
Delete
|
|
9024
|
7294
|
6
|
5
|
339ea969ec2633756fb1a155d47723d0f61396a4
|
0
|
🔒 多租户安全审计
|
1
|
name: Code Quality Gate
"on":
push:
name: Code Quality Gate
"on":
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
strict_mode:
description: '严格模式(失败即阻止合并)'
required: false
default: true
type: boolean
env:
COVERAGE_THRESHOLD_E2E: "60"
COVERAGE_THRESHOLD_INTEGRATION: "70"
COVERAGE_THRESHOLD_UNIT: "80"
NODE_VERSION: "20"
PNPM_VERSION: "8"
jobs:
tenant-security:
name: "\U0001F512 多租户安全审计"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装 pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
cache: pnpm
node-version: ${{ env.NODE_VERSION }}
- name: 安装依赖
run: pnpm install --frozen-lockfile
- name: 生成 Prisma Client
run: pnpm --filter juhi-api run db:generate
- id: tenant-audit
name: 执行多租户安全审计
run: |
cd backend
npm run audit:tenant 2>&1 | tee audit-result.txt
if grep -q "FAIL" audit-result.txt; then
echo "❌ 多租户安全审计失败"
echo "has_failures=true" >> $GITHUB_OUTPUT
exit 1
fi
echo "✅ 多租户安全审计通过"
echo "has_failures=false" >> $GITHUB_OUTPUT
- if: always()
name: 上传审计报告
uses: actions/upload-artifact@v4
with:
name: tenant-security-audit
path: backend/audit-result.txt
retention-days: "30"
timeout-minutes: "15"
...
|
tenant-security
|
null
|
["ubuntu-latest"]
|
7774
|
2
|
1774229443
|
1774229460
|
1774229064
|
1774229461
|
|
0
|
|
0
|
Edit
Delete
|