qaify-playwright-reporter 0.9.7 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/command.d.ts +19 -0
- package/dist/agent/command.js +76 -0
- package/dist/agent/llm.d.ts +46 -0
- package/dist/agent/llm.js +111 -0
- package/dist/agent/mcp.d.ts +31 -0
- package/dist/agent/mcp.js +115 -0
- package/dist/agent/run.d.ts +56 -0
- package/dist/agent/run.js +177 -0
- package/dist/agent/tools.d.ts +22 -0
- package/dist/agent/tools.js +250 -0
- package/dist/ai-env.d.ts +29 -0
- package/dist/ai-env.js +89 -0
- package/dist/analyze.d.ts +12 -0
- package/dist/analyze.js +12 -0
- package/dist/audit.js +35 -32
- package/dist/cli.js +69 -20
- package/dist/fix.js +56 -50
- package/dist/init.d.ts +2 -2
- package/dist/init.js +51 -47
- package/dist/usage.d.ts +7 -0
- package/dist/usage.js +20 -0
- package/package.json +51 -51
- package/templates/auto-fix.yml +47 -12
- package/templates/qa.yml +37 -6
- package/templates/qaify-audit.yml +58 -17
- package/templates/qaify-fix.yml +48 -14
package/templates/qa.yml
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
# Butuh di repo ini (Settings → Secrets and variables → Actions):
|
|
3
3
|
# secret QA_FACTORY_TOKEN token reporter dari Pengaturan → Token Reporter
|
|
4
4
|
# variable QA_FACTORY_URL URL API QA Factory
|
|
5
|
-
# secret CLAUDE_CODE_OAUTH_TOKEN opsional, analisis AI dengan langganan Claude Pro/Max Anda (`claude setup-token`)
|
|
6
|
-
#
|
|
5
|
+
# secret CLAUDE_CODE_OAUTH_TOKEN opsional, analisis AI dengan langganan Claude Pro/Max Anda (`claude setup-token`);
|
|
6
|
+
# atau pakai API key sendiri di Qaify → Setelan → Agen AI (Analis)
|
|
7
|
+
# variable QA_FACTORY_AI_MODEL opsional, default sonnet (langganan tanpa model dari Qaify)
|
|
7
8
|
# dan devDependency qaify-playwright-reporter (sudah terpasang bila Anda menjalankan `npx qaify init`).
|
|
8
9
|
# Nama file harus tetap qa.yml.
|
|
9
10
|
name: QA
|
|
@@ -61,28 +62,58 @@ jobs:
|
|
|
61
62
|
npx qaify ai-queue --out "$RUNNER_TEMP/qaf/queue.json"
|
|
62
63
|
npx qaify ai-schema --out "$RUNNER_TEMP/qaf/schema.json" --instructions "$RUNNER_TEMP/qaf/instructions.txt"
|
|
63
64
|
|
|
65
|
+
# mesin + model + API key agen Analis (Qaify → Setelan → Agen AI; admin repo memilih "pakai setelan Agen AI
|
|
66
|
+
# akun saya"). Reporter lama tanpa perintah ini → langganan Claude seperti biasa.
|
|
67
|
+
- name: Pilih agen AI
|
|
68
|
+
id: ai
|
|
69
|
+
if: steps.queue.outputs.count != '0'
|
|
70
|
+
continue-on-error: true
|
|
71
|
+
run: npx qaify ai-env --kind analyze --env-file "$RUNNER_TEMP/qaify-ai.env" --error-out "$RUNNER_TEMP/qaf/claude.json"
|
|
72
|
+
|
|
64
73
|
# folder kosong: .claude/ dan .mcp.json milik repo tidak ikut termuat; semua tool dimatikan
|
|
65
|
-
- name: Analisis dengan Claude Code
|
|
66
|
-
if:
|
|
74
|
+
- name: Analisis dengan Claude Code
|
|
75
|
+
if: >-
|
|
76
|
+
steps.queue.outputs.count != '0' && (steps.ai.outputs.engine || 'claude_code') == 'claude_code'
|
|
77
|
+
&& (env.HAS_CLAUDE == 'true' || steps.ai.outputs.has_key == 'true')
|
|
67
78
|
continue-on-error: true
|
|
68
79
|
timeout-minutes: 5
|
|
69
80
|
working-directory: ${{ runner.temp }}/qaf
|
|
70
81
|
env:
|
|
71
82
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
83
|
+
MODEL: ${{ steps.ai.outputs.model || vars.QA_FACTORY_AI_MODEL || 'sonnet' }}
|
|
72
84
|
run: |
|
|
73
85
|
npm install -g @anthropic-ai/claude-code
|
|
86
|
+
# API key Anthropic dari Qaify menggantikan langganan
|
|
87
|
+
if [ -f "$RUNNER_TEMP/qaify-ai.env" ]; then
|
|
88
|
+
set -a; . "$RUNNER_TEMP/qaify-ai.env"; set +a
|
|
89
|
+
rm -f "$RUNNER_TEMP/qaify-ai.env"; unset CLAUDE_CODE_OAUTH_TOKEN
|
|
90
|
+
fi
|
|
74
91
|
claude -p "Analisis setiap kegagalan test pada input JSON." \
|
|
75
|
-
--model "$
|
|
92
|
+
--model "$MODEL" \
|
|
76
93
|
--tools "" --disallowedTools "mcp__*" --strict-mcp-config \
|
|
77
94
|
--max-turns 3 --no-session-persistence \
|
|
78
95
|
--append-system-prompt "$(cat instructions.txt)" \
|
|
79
96
|
--output-format json --json-schema "$(cat schema.json)" \
|
|
80
97
|
< queue.json > claude.json
|
|
81
98
|
|
|
99
|
+
# Qaify Agent (API key OpenRouter / OpenAI / Gemini / …): tanpa tool, key hanya di memori proses agen
|
|
100
|
+
- name: Analisis dengan Qaify Agent (API key)
|
|
101
|
+
if: steps.queue.outputs.count != '0' && steps.ai.outputs.engine == 'qaify_agent'
|
|
102
|
+
continue-on-error: true
|
|
103
|
+
timeout-minutes: 5
|
|
104
|
+
run: |
|
|
105
|
+
echo "Analisis setiap kegagalan test pada input JSON." > "$RUNNER_TEMP/qaf/prompt.txt"
|
|
106
|
+
npx qaify agent --env-file "$RUNNER_TEMP/qaify-ai.env" \
|
|
107
|
+
--prompt-file "$RUNNER_TEMP/qaf/prompt.txt" --input-file "$RUNNER_TEMP/qaf/queue.json" \
|
|
108
|
+
--instructions-file "$RUNNER_TEMP/qaf/instructions.txt" --schema-file "$RUNNER_TEMP/qaf/schema.json" \
|
|
109
|
+
--max-turns 3 --out "$RUNNER_TEMP/qaf/claude.json"
|
|
110
|
+
|
|
82
111
|
# selalu jalan: hasil yang ada diterapkan, sisa antrean (gagal / kuota habis / tanpa secret) → belum jelas
|
|
83
112
|
- name: Kirim hasil analisis
|
|
84
113
|
if: always()
|
|
85
|
-
run:
|
|
114
|
+
run: |
|
|
115
|
+
rm -f "$RUNNER_TEMP/qaify-ai.env"
|
|
116
|
+
npx qaify ai-submit --results "$RUNNER_TEMP/qaf/claude.json" --finalize
|
|
86
117
|
|
|
87
118
|
# Sharding: jadikan job `test` matrix, mis.
|
|
88
119
|
# strategy: { matrix: { shard: ["1/2", "2/2"] } }
|
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
# Butuh di repo runner ini (Settings → Secrets and variables → Actions):
|
|
4
4
|
# secret QA_FACTORY_TOKEN token reporter repo runner (Pengaturan → Token Reporter)
|
|
5
5
|
# variable QA_FACTORY_URL URL API Qaify
|
|
6
|
-
# secret CLAUDE_CODE_OAUTH_TOKEN opsional:
|
|
6
|
+
# secret CLAUDE_CODE_OAUTH_TOKEN opsional: agen yang memakai langganan Claude Pro/Max (`claude setup-token`);
|
|
7
|
+
# tidak perlu bila semua agen memakai API key (Qaify → Setelan → Agen AI)
|
|
7
8
|
# variable QA_FACTORY_AUDIT_MODE opsional, `static` / `claude`; hanya dipakai bila Qaify tidak mengirim mode
|
|
8
|
-
# variable QA_FACTORY_AI_MODEL opsional, default sonnet
|
|
9
|
+
# variable QA_FACTORY_AI_MODEL opsional, default sonnet (langganan tanpa model dari Qaify)
|
|
9
10
|
# variable QA_FACTORY_MCP_VERSION opsional, versi @playwright/mcp (default latest)
|
|
10
11
|
# GitHub App Qaify harus terpasang di repo ini dan di repo FE + BE. Nama file harus tetap qaify-audit.yml.
|
|
11
|
-
# Mode audit dipilih di Qaify (setelan aplikasi, bisa diganti per audit)
|
|
12
|
+
# Mode audit dipilih di Qaify (setelan aplikasi, bisa diganti per audit). Mode AI memakai agen "Auditor" dari
|
|
13
|
+
# Setelan → Agen AI: Claude Code (langganan / API key Anthropic) atau Qaify Agent (API key OpenRouter, OpenAI,
|
|
14
|
+
# Gemini, …). API key diambil dari Qaify tepat sebelum audit (`qaify ai-env`) dan disamarkan di log.
|
|
15
|
+
# Mode AI tanpa langganan maupun API key jatuh ke static.
|
|
12
16
|
# Mode static (tanpa AI): build, test, composer/npm audit, dan smoke test Playwright; cepat, tanpa kuota AI,
|
|
13
|
-
# tetapi tanpa analisis logika bisnis / kontrak API dari kode. Temuannya tetap bisa diperbaiki
|
|
14
|
-
# Mode claude: satu sesi Claude yang panjang; kuota langganan dipakai bersama pemakaian pribadi.
|
|
17
|
+
# tetapi tanpa analisis logika bisnis / kontrak API dari kode. Temuannya tetap bisa diperbaiki agen AI (qaify-fix.yml).
|
|
15
18
|
name: Qaify audit
|
|
16
19
|
run-name: audit ${{ inputs.audit_id }}
|
|
17
20
|
on:
|
|
@@ -44,7 +47,7 @@ jobs:
|
|
|
44
47
|
ports: ['5432:5432']
|
|
45
48
|
options: --health-cmd="pg_isready -U postgres" --health-interval=10s --health-timeout=5s --health-retries=10
|
|
46
49
|
# context runner tidak tersedia di env level job; WORK diisi lewat GITHUB_ENV di step pertama,
|
|
47
|
-
# AUDIT_MODE di step "Tentukan mode audit" (
|
|
50
|
+
# AUDIT_MODE & AUDIT_ENGINE di step "Tentukan mode audit" (baru diketahui dari Qaify)
|
|
48
51
|
steps:
|
|
49
52
|
- name: Siapkan direktori kerja
|
|
50
53
|
run: echo "WORK=$RUNNER_TEMP/qaify" >> "$GITHUB_ENV"
|
|
@@ -58,7 +61,7 @@ jobs:
|
|
|
58
61
|
tools: composer
|
|
59
62
|
|
|
60
63
|
- name: Pasang Qaify CLI
|
|
61
|
-
run: npm install -g qaify-playwright-reporter@0.
|
|
64
|
+
run: npm install -g qaify-playwright-reporter@0.10 playwright-core@1
|
|
62
65
|
|
|
63
66
|
# token clone sekali pakai (read-only, hanya repo FE + BE) dicabut sebelum auditor berjalan
|
|
64
67
|
- name: Ambil konteks & clone repo FE + BE
|
|
@@ -68,24 +71,42 @@ jobs:
|
|
|
68
71
|
QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
|
|
69
72
|
run: qaify audit-context --audit "${{ inputs.audit_id }}" --dir "$WORK"
|
|
70
73
|
|
|
71
|
-
#
|
|
74
|
+
# mesin + model + API key agen Auditor; key ke berkas di luar folder kerja, disamarkan di log
|
|
75
|
+
- name: Pilih agen AI
|
|
76
|
+
id: ai
|
|
77
|
+
if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'static'
|
|
78
|
+
continue-on-error: true
|
|
79
|
+
env:
|
|
80
|
+
QA_FACTORY_URL: ${{ vars.QA_FACTORY_URL }}
|
|
81
|
+
QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
|
|
82
|
+
run: |
|
|
83
|
+
qaify ai-env --kind audit --id "${{ inputs.audit_id }}" \
|
|
84
|
+
--env-file "$RUNNER_TEMP/qaify-ai.env" --error-out "$WORK/.qaify/claude.json"
|
|
85
|
+
|
|
86
|
+
# pilihan Qaify → variable QA_FACTORY_AUDIT_MODE → claude bila secret ada; AI tanpa langganan / API key → static
|
|
72
87
|
- name: Tentukan mode audit
|
|
73
88
|
if: steps.ctx.outputs.ok == 'true'
|
|
74
89
|
env:
|
|
75
90
|
REQUESTED: ${{ steps.ctx.outputs.mode || vars.QA_FACTORY_AUDIT_MODE }}
|
|
76
91
|
HAS_CLAUDE: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
|
|
92
|
+
HAS_KEY: ${{ steps.ai.outputs.has_key }}
|
|
93
|
+
ENGINE: ${{ steps.ai.outputs.engine || 'claude_code' }}
|
|
77
94
|
run: |
|
|
78
95
|
mode="${REQUESTED:-$([ "$HAS_CLAUDE" = true ] && echo claude || echo static)}"
|
|
79
96
|
if [ "$mode" != static ] && [ "$mode" != claude ]; then
|
|
80
97
|
echo "::warning::Mode audit tidak dikenal ($mode); memakai static."
|
|
81
98
|
mode=static
|
|
82
99
|
fi
|
|
83
|
-
if [ "$mode" = claude ] && [ "$
|
|
84
|
-
|
|
100
|
+
if [ "$mode" = claude ] && [ "$ENGINE" = none ]; then
|
|
101
|
+
# hasil gagal + penyebabnya sudah ditulis step "Pilih agen AI"
|
|
102
|
+
mode=failed
|
|
103
|
+
elif [ "$mode" = claude ] && [ "$HAS_CLAUDE" != true ] && [ "$HAS_KEY" != true ]; then
|
|
104
|
+
echo "::warning::Mode AI diminta tetapi secret CLAUDE_CODE_OAUTH_TOKEN kosong dan agen Auditor tidak memakai API key; audit dijalankan tanpa AI."
|
|
85
105
|
mode=static
|
|
86
106
|
fi
|
|
87
|
-
echo "qa-factory: mode audit $mode"
|
|
107
|
+
echo "qa-factory: mode audit $mode ($ENGINE)"
|
|
88
108
|
echo "AUDIT_MODE=$mode" >> "$GITHUB_ENV"
|
|
109
|
+
echo "AUDIT_ENGINE=$ENGINE" >> "$GITHUB_ENV"
|
|
89
110
|
|
|
90
111
|
# tanpa secret apa pun: kode aplikasi (composer/npm script) berjalan di step ini
|
|
91
112
|
- name: Audit tanpa AI (Playwright)
|
|
@@ -97,25 +118,32 @@ jobs:
|
|
|
97
118
|
- name: Siapkan instruksi & Playwright MCP
|
|
98
119
|
if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude'
|
|
99
120
|
run: |
|
|
100
|
-
npm install -g @anthropic-ai/claude-code
|
|
121
|
+
if [ "$AUDIT_ENGINE" = claude_code ]; then npm install -g @anthropic-ai/claude-code; fi
|
|
101
122
|
mkdir -p "$WORK/.qaify"
|
|
102
123
|
qaify audit-schema --out "$WORK/.qaify/schema.json" --instructions "$WORK/.qaify/instructions.txt"
|
|
124
|
+
qaify audit-schema --prompt > "$WORK/.qaify/prompt.txt"
|
|
103
125
|
# Google Chrome sudah ada di runner ubuntu-latest
|
|
104
126
|
cat > "$WORK/.qaify/mcp.json" <<JSON
|
|
105
127
|
{"mcpServers":{"playwright":{"command":"npx","args":["-y","@playwright/mcp@${{ vars.QA_FACTORY_MCP_VERSION || 'latest' }}","--headless","--isolated","--browser","chrome","--output-dir","$WORK/evidence"]}}}
|
|
106
128
|
JSON
|
|
107
129
|
|
|
108
|
-
# hanya
|
|
109
|
-
- name: Audit dengan Claude Code
|
|
110
|
-
if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude'
|
|
130
|
+
# hanya kredensial AI (secret langganan / API key Anthropic dari Qaify) di step ini; QA_FACTORY_TOKEN tidak
|
|
131
|
+
- name: Audit dengan Claude Code
|
|
132
|
+
if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude' && env.AUDIT_ENGINE == 'claude_code'
|
|
111
133
|
continue-on-error: true
|
|
112
134
|
timeout-minutes: 45
|
|
113
135
|
working-directory: ${{ runner.temp }}/qaify
|
|
114
136
|
env:
|
|
115
137
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
138
|
+
MODEL: ${{ steps.ai.outputs.model || vars.QA_FACTORY_AI_MODEL || 'sonnet' }}
|
|
116
139
|
run: |
|
|
117
|
-
|
|
118
|
-
|
|
140
|
+
# API key Anthropic dari Qaify menggantikan langganan
|
|
141
|
+
if [ -f "$RUNNER_TEMP/qaify-ai.env" ]; then
|
|
142
|
+
set -a; . "$RUNNER_TEMP/qaify-ai.env"; set +a
|
|
143
|
+
rm -f "$RUNNER_TEMP/qaify-ai.env"; unset CLAUDE_CODE_OAUTH_TOKEN
|
|
144
|
+
fi
|
|
145
|
+
claude -p "$(cat .qaify/prompt.txt)" \
|
|
146
|
+
--model "$MODEL" \
|
|
119
147
|
--allowedTools "Bash,Read,Grep,Glob,Write,Edit,mcp__playwright" \
|
|
120
148
|
--disallowedTools "WebFetch,WebSearch" \
|
|
121
149
|
--strict-mcp-config --mcp-config .qaify/mcp.json \
|
|
@@ -124,6 +152,18 @@ jobs:
|
|
|
124
152
|
--output-format json --json-schema "$(cat .qaify/schema.json)" \
|
|
125
153
|
> .qaify/claude.json
|
|
126
154
|
|
|
155
|
+
# Qaify Agent: key hanya di memori proses agen (berkas env dihapus saat dibaca), tidak diwarisi bash / MCP
|
|
156
|
+
- name: Audit dengan Qaify Agent (API key)
|
|
157
|
+
if: steps.ctx.outputs.ok == 'true' && env.AUDIT_MODE == 'claude' && env.AUDIT_ENGINE == 'qaify_agent'
|
|
158
|
+
continue-on-error: true
|
|
159
|
+
timeout-minutes: 45
|
|
160
|
+
working-directory: ${{ runner.temp }}/qaify
|
|
161
|
+
run: |
|
|
162
|
+
qaify agent --env-file "$RUNNER_TEMP/qaify-ai.env" \
|
|
163
|
+
--prompt-file .qaify/prompt.txt --instructions-file .qaify/instructions.txt --schema-file .qaify/schema.json \
|
|
164
|
+
--tools read,list,grep,write,edit,bash --mcp-config .qaify/mcp.json --max-turns 150 \
|
|
165
|
+
--out .qaify/claude.json
|
|
166
|
+
|
|
127
167
|
# selalu jalan (juga saat konteks/clone gagal): tanpa hasil auditor, audit ditandai gagal beserta penyebabnya
|
|
128
168
|
- name: Kirim hasil audit
|
|
129
169
|
if: always()
|
|
@@ -131,5 +171,6 @@ jobs:
|
|
|
131
171
|
QA_FACTORY_URL: ${{ vars.QA_FACTORY_URL }}
|
|
132
172
|
QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
|
|
133
173
|
run: |
|
|
174
|
+
rm -f "$RUNNER_TEMP/qaify-ai.env"
|
|
134
175
|
qaify audit-submit --audit "${{ inputs.audit_id }}" \
|
|
135
176
|
--results "$WORK/.qaify/claude.json" --evidence "$WORK/evidence" --context "$WORK/context.json"
|
package/templates/qaify-fix.yml
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
# Qaify — perbaikan temuan audit oleh
|
|
2
|
-
# Dipicu Qaify lewat workflow_dispatch (otomatis setelah audit, atau tombol "Perbaiki
|
|
1
|
+
# Qaify — perbaikan temuan audit oleh agen AI (1 temuan = 1 PR ke repo FE/BE). Dibuat oleh `npx qaify init-runner`.
|
|
2
|
+
# Dipicu Qaify lewat workflow_dispatch (otomatis setelah audit, atau tombol "Perbaiki"); satu per satu per aplikasi.
|
|
3
3
|
# Butuh di repo runner ini (sama dengan qaify-audit.yml):
|
|
4
4
|
# secret QA_FACTORY_TOKEN token reporter repo runner
|
|
5
5
|
# variable QA_FACTORY_URL URL API Qaify
|
|
6
|
-
# secret CLAUDE_CODE_OAUTH_TOKEN langganan Claude Pro/Max Anda (`claude setup-token`);
|
|
6
|
+
# secret CLAUDE_CODE_OAUTH_TOKEN langganan Claude Pro/Max Anda (`claude setup-token`); hanya untuk engineer yang
|
|
7
|
+
# memakai langganan (tidak perlu bila semua engineer memakai API key di Qaify)
|
|
7
8
|
# GitHub App Qaify butuh izin Contents: Read and write dan Pull requests: Read and write di repo FE/BE.
|
|
8
|
-
#
|
|
9
|
-
#
|
|
9
|
+
# Engineer (Nanda / Fajar / Pak Yoga) dipilih Qaify per temuan menurut kompleksitas atau pilihan Anda; mesin, model,
|
|
10
|
+
# dan API key-nya dari Setelan → Agen AI (Claude Code dengan langganan / API key Anthropic, atau Qaify Agent dengan
|
|
11
|
+
# API key OpenRouter, OpenAI, Gemini, …). API key diambil tepat sebelum perbaikan (`qaify ai-env`), disamarkan di log.
|
|
12
|
+
# Advisory dependensi (composer.lock / package-lock.json) diperbaiki tanpa AI: `qaify fix-deps` memperbarui
|
|
10
13
|
# paketnya di lockfile (mode deps), tanpa memakai kuota.
|
|
11
|
-
# Job "fix" menjalankan
|
|
14
|
+
# Job "fix" menjalankan agen tanpa token push; job "submit" (VM bersih) meng-clone ulang, menerapkan patch, lalu push.
|
|
12
15
|
# Nama file harus tetap qaify-fix.yml.
|
|
13
16
|
name: Qaify fix
|
|
14
17
|
run-name: fix ${{ inputs.fix_id }}
|
|
@@ -55,10 +58,10 @@ jobs:
|
|
|
55
58
|
extensions: mbstring, intl, bcmath, gd, zip, pdo_mysql, pdo_pgsql
|
|
56
59
|
tools: composer
|
|
57
60
|
|
|
58
|
-
- name: Pasang Qaify CLI
|
|
59
|
-
run: npm install -g qaify-playwright-reporter@0.
|
|
61
|
+
- name: Pasang Qaify CLI
|
|
62
|
+
run: npm install -g qaify-playwright-reporter@0.10
|
|
60
63
|
|
|
61
|
-
# token clone sekali pakai (read-only, hanya repo target) dicabut sebelum
|
|
64
|
+
# token clone sekali pakai (read-only, hanya repo target) dicabut sebelum agen berjalan
|
|
62
65
|
- name: Ambil temuan & clone repo target
|
|
63
66
|
id: ctx
|
|
64
67
|
env:
|
|
@@ -75,16 +78,34 @@ jobs:
|
|
|
75
78
|
timeout-minutes: 15
|
|
76
79
|
run: qaify fix-deps --dir "$WORK"
|
|
77
80
|
|
|
78
|
-
#
|
|
79
|
-
- name:
|
|
81
|
+
# mesin + model + API key engineer; key ke berkas di luar folder kerja, disamarkan di log
|
|
82
|
+
- name: Pilih agen AI
|
|
83
|
+
id: ai
|
|
80
84
|
if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'deps'
|
|
81
85
|
continue-on-error: true
|
|
86
|
+
env:
|
|
87
|
+
QA_FACTORY_URL: ${{ vars.QA_FACTORY_URL }}
|
|
88
|
+
QA_FACTORY_TOKEN: ${{ secrets.QA_FACTORY_TOKEN }}
|
|
89
|
+
run: |
|
|
90
|
+
qaify ai-env --kind audit_fix --id "${{ inputs.fix_id }}" \
|
|
91
|
+
--env-file "$RUNNER_TEMP/qaify-ai.env" --error-out "$WORK/.qaify/claude.json"
|
|
92
|
+
|
|
93
|
+
# hanya kredensial AI (secret langganan / API key Anthropic dari Qaify); tidak ada token Qaify maupun token push
|
|
94
|
+
- name: Perbaiki dengan Claude Code
|
|
95
|
+
if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'deps' && (steps.ai.outputs.engine || 'claude_code') == 'claude_code'
|
|
96
|
+
continue-on-error: true
|
|
82
97
|
timeout-minutes: 45
|
|
83
98
|
working-directory: ${{ runner.temp }}/qaify/repo
|
|
84
99
|
env:
|
|
85
100
|
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
86
|
-
MODEL: ${{ steps.ctx.outputs.model }}
|
|
101
|
+
MODEL: ${{ steps.ai.outputs.model || steps.ctx.outputs.model }}
|
|
87
102
|
run: |
|
|
103
|
+
npm install -g @anthropic-ai/claude-code
|
|
104
|
+
# API key Anthropic dari Qaify menggantikan langganan
|
|
105
|
+
if [ -f "$RUNNER_TEMP/qaify-ai.env" ]; then
|
|
106
|
+
set -a; . "$RUNNER_TEMP/qaify-ai.env"; set +a
|
|
107
|
+
rm -f "$RUNNER_TEMP/qaify-ai.env"; unset CLAUDE_CODE_OAUTH_TOKEN
|
|
108
|
+
fi
|
|
88
109
|
claude -p "$(cat ../.qaify/prompt.txt)" \
|
|
89
110
|
--model "$MODEL" \
|
|
90
111
|
--allowedTools "Bash,Read,Grep,Glob,Write,Edit" \
|
|
@@ -94,9 +115,22 @@ jobs:
|
|
|
94
115
|
--output-format json --json-schema "$(cat ../.qaify/schema.json)" \
|
|
95
116
|
> ../.qaify/claude.json
|
|
96
117
|
|
|
118
|
+
# Qaify Agent: key hanya di memori proses agen (berkas env dihapus saat dibaca), tidak diwarisi bash
|
|
119
|
+
- name: Perbaiki dengan Qaify Agent (API key)
|
|
120
|
+
if: steps.ctx.outputs.ok == 'true' && steps.ctx.outputs.mode != 'deps' && steps.ai.outputs.engine == 'qaify_agent'
|
|
121
|
+
continue-on-error: true
|
|
122
|
+
timeout-minutes: 45
|
|
123
|
+
working-directory: ${{ runner.temp }}/qaify/repo
|
|
124
|
+
run: |
|
|
125
|
+
qaify agent --env-file "$RUNNER_TEMP/qaify-ai.env" \
|
|
126
|
+
--prompt-file ../.qaify/prompt.txt --instructions-file ../.qaify/instructions.txt --schema-file ../.qaify/schema.json \
|
|
127
|
+
--tools read,list,grep,write,edit,bash --max-turns 80 \
|
|
128
|
+
--out ../.qaify/claude.json
|
|
129
|
+
|
|
97
130
|
- name: Kumpulkan perubahan
|
|
98
131
|
if: always() && steps.ctx.outputs.ok == 'true'
|
|
99
132
|
run: |
|
|
133
|
+
rm -f "$RUNNER_TEMP/qaify-ai.env"
|
|
100
134
|
qaify fix-diff --dir "$WORK" --out "$WORK/out"
|
|
101
135
|
cp "$WORK/.qaify/claude.json" "$WORK/out/claude.json" 2>/dev/null || true
|
|
102
136
|
|
|
@@ -108,7 +142,7 @@ jobs:
|
|
|
108
142
|
retention-days: 3
|
|
109
143
|
if-no-files-found: ignore
|
|
110
144
|
|
|
111
|
-
# selalu jalan setelah konteks diambil: tanpa hasil
|
|
145
|
+
# selalu jalan setelah konteks diambil: tanpa hasil agen, perbaikan ditandai gagal beserta penyebab yang mungkin
|
|
112
146
|
submit:
|
|
113
147
|
needs: fix
|
|
114
148
|
if: always() && needs.fix.outputs.ok == 'true'
|
|
@@ -118,7 +152,7 @@ jobs:
|
|
|
118
152
|
- uses: actions/setup-node@v4
|
|
119
153
|
with: { node-version: 22 }
|
|
120
154
|
- name: Pasang Qaify CLI
|
|
121
|
-
run: npm install -g qaify-playwright-reporter@0.
|
|
155
|
+
run: npm install -g qaify-playwright-reporter@0.10
|
|
122
156
|
- uses: actions/download-artifact@v4
|
|
123
157
|
continue-on-error: true
|
|
124
158
|
with:
|