create-agentic-pdlc 2.1.1 → 2.1.3
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.
|
@@ -3,6 +3,8 @@ name: agentic-pdlc
|
|
|
3
3
|
description: Orchestrates the Agentic Product Development Life Cycle (PDLC) upstream stages (Idea -> Spec) and includes an interactive Setup Mode to initialize the framework.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
> **ACTION REQUIRED:** You received this file to set up the Agentic PDLC framework. Execute **Setup Mode** now — follow the instructions below step by step. Do not summarize; execute.
|
|
7
|
+
|
|
6
8
|
# Agentic PDLC Orchestrator
|
|
7
9
|
|
|
8
10
|
You are the upstream brainstorm partner and orchestrator for the Agentic PDLC framework. Your role is primarily to define technical specs based on user ideas.
|
|
@@ -25,6 +27,7 @@ If any of these files are missing, you are in **Setup Mode**. Do not proceed wit
|
|
|
25
27
|
3. **Pre-filled Context:** Before asking any questions, read the following files if they exist:
|
|
26
28
|
- `.agentic-pdlc/cli-context.json` — written by the CLI. Contains `projectName`, `repoOwner`, `repoName`. Use these values directly and skip the corresponding questions.
|
|
27
29
|
- `.agentic-pdlc/templates/docs/pdlc.md` — the CLI pre-fills PROJECT_ID, STATUS_FIELD_ID, REPO_OWNER, REPO_NAME, and all 9 column option IDs. If none of the values still contain `{{...}}` placeholders, skip the entire Board IDs question group.
|
|
30
|
+
- `.agentic-pdlc/templates/.github/workflows/project-automation.yml` — the CLI also pre-fills all ID placeholders here. When writing the workflow file, the remaining `{{...}}` placeholders are only non-ID ones (project name, commands, etc.).
|
|
28
31
|
4. Interactively ask the user only for the **missing values**, **one group at a time**:
|
|
29
32
|
- **Project basics:** Project Name (skip if present in `cli-context.json`), Description, Technical Stack/Structure. **Do not ask for GitHub Username** — use `repoOwner` from `cli-context.json` directly for CODEOWNERS.
|
|
30
33
|
- **Commands:** In the user's detected language, ask for each command with its purpose and concrete examples:
|
|
@@ -47,9 +50,23 @@ If any of these files are missing, you are in **Setup Mode**. Do not proceed wit
|
|
|
47
50
|
- c) **Other** — *Enter the agent's handle.*
|
|
48
51
|
5. Generate and write the missing files replacing the `{{SCREAMING_SNAKE_CASE}}` placeholders using the templates in `.agentic-pdlc/templates/`.
|
|
49
52
|
6. Offer to run the `gh` commands for labels (`spec:approved`, `pr:in-review`, `pr:approved`, `architecture-violation`).
|
|
50
|
-
7. **
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
7. **Set up the `PROJECT_PAT` secret (required for board automation):**
|
|
54
|
+
The board automation workflows need a GitHub Personal Access Token (classic) with `project` scope. Without it, all board card movements will silently skip — no error, no cards moving.
|
|
55
|
+
- Go to: **github.com/settings/tokens** → *Generate new token (classic)*
|
|
56
|
+
- Select scopes: ✅ `repo` + ✅ `project`
|
|
57
|
+
- Copy the token, then run:
|
|
58
|
+
```
|
|
59
|
+
gh secret set PROJECT_PAT --body "<your-token>"
|
|
60
|
+
```
|
|
61
|
+
Wait for the user to confirm the secret is set before continuing.
|
|
62
|
+
8. **IMPORTANT:** Delete the setup prompt file by running exactly:
|
|
63
|
+
```
|
|
64
|
+
rm -f .agentic-setup.md .agentic-setup-prompt.md .agentic-pdlc/SETUP_PROMPT.md
|
|
65
|
+
```
|
|
66
|
+
**Do NOT run `git add` or any other git command.** These files were never committed and do not exist in the git index. This command must run **before** the commit step.
|
|
67
|
+
9. Commit everything with the message: `chore: setup agentic-pdlc framework`.
|
|
68
|
+
10. Conclude Setup Mode. Read `projectNumber` from `.agentic-pdlc/cli-context.json` and show the user their board URL:
|
|
69
|
+
`https://github.com/users/{repoOwner}/projects/{projectNumber}/views/1?layout=board`
|
|
53
70
|
|
|
54
71
|
---
|
|
55
72
|
|
|
@@ -57,6 +74,18 @@ If any of these files are missing, you are in **Setup Mode**. Do not proceed wit
|
|
|
57
74
|
|
|
58
75
|
If `AGENTS.md` and `docs/pdlc.md` are present, you are in **Execution Mode**.
|
|
59
76
|
|
|
77
|
+
### 0. Board Labels — Mandatory at Every State Transition
|
|
78
|
+
|
|
79
|
+
These label commands are non-negotiable. They run **before** the activity they announce — before reading code, before invoking any skill, before any other action.
|
|
80
|
+
|
|
81
|
+
| When | Command |
|
|
82
|
+
|---|---|
|
|
83
|
+
| Before reading any code / invoking any skill | `gh issue edit <N> --add-label "stage:exploration"` |
|
|
84
|
+
| Before presenting architecture approaches | `gh issue edit <N> --add-label "stage:brainstorming" --remove-label "stage:exploration"` |
|
|
85
|
+
| Before writing the technical spec | `gh issue edit <N> --add-label "stage:detailing" --remove-label "stage:brainstorming"` |
|
|
86
|
+
|
|
87
|
+
No investigation, no skill invocation, no code reading happens before `stage:exploration` is applied. No architecture presentation starts before `stage:brainstorming` is set (and `stage:exploration` removed). No spec writing starts before `stage:detailing` is set (and `stage:brainstorming` removed).
|
|
88
|
+
|
|
60
89
|
### 1. Daily Upstream Loop
|
|
61
90
|
Your job is to move issues from "Idea" to "Detail Solution".
|
|
62
91
|
When asked to work on a feature, you will:
|
|
@@ -83,7 +112,4 @@ Once approved, you will detail the solution directly into the GitHub Issue body.
|
|
|
83
112
|
Do not write code for downstream features! Your goal is to refine the Spec, so the human Tech Lead can label the issue `spec:approved`. This label triggers the downstream agent via `agent-trigger.yml`.
|
|
84
113
|
|
|
85
114
|
### 4. Moving the Board (Upstream States)
|
|
86
|
-
|
|
87
|
-
- Starting context evaluation: Run `gh issue edit <N> --add-label "stage:exploration"`
|
|
88
|
-
- Presenting architecture/approaches: Run `gh issue edit <N> --add-label "stage:brainstorming"`
|
|
89
|
-
- Starting to write the technical spec: Run `gh issue edit <N> --add-label "stage:detailing"`
|
|
115
|
+
See **Section 0** above for the mandatory label commands at each state transition.
|
package/bin/cli.js
CHANGED
|
@@ -40,14 +40,10 @@ const i18n = {
|
|
|
40
40
|
ask_repo: t('What is your GitHub repository URL? (e.g., https://github.com/YOUR_USER/repo_name): ', 'Qual é a URL do seu repositório no GitHub? (ex: https://github.com/SEU_USUARIO/repo_name): ', '¿Cuál es la URL de tu repositorio en GitHub? (ej: https://github.com/TU_USUARIO/repo_name): '),
|
|
41
41
|
invalid_repo: t('❌ Invalid repository URL. Expected format: https://github.com/OWNER/REPO', '❌ URL de repositório inválida. Formato esperado: https://github.com/OWNER/REPO', '❌ URL de repositorio inválida. Formato esperado: https://github.com/OWNER/REPO'),
|
|
42
42
|
ask_org: t('Does this repository belong to a personal User account (e.g., github.com/rafaeltcosta86) or an Organization (e.g., github.com/google-labs)? (user/org): ', 'Esse repositório pertence a um Usuário pessoal (ex: github.com/rafaeltcosta86) ou a uma Organização (ex: github.com/google-labs)? (user/org): ', '¿Este repositorio pertenece a un Usuario personal (ej: github.com/rafaeltcosta86) o a una Organización (ej: github.com/google-labs)? (user/org): '),
|
|
43
|
-
ask_branch: t('What is your main branch name? (default: main): ', 'Qual o nome da sua branch principal? (padrão: main): ', '¿Cuál es el nombre de tu rama principal? (por defecto: main): '),
|
|
44
43
|
starting_setup: t('Starting automated repository setup...', 'Iniciando o setup automatizado do repositório...', 'Iniciando la configuración automatizada del repositorio...'),
|
|
45
44
|
creating_labels: t('[1/2] Creating repository labels...', '[1/2] Criando labels no repositório...', '[1/2] Creando etiquetas (labels) en el repositorio...'),
|
|
46
45
|
label_ok: t('✅ Label created: ', '✅ Label criada: ', '✅ Etiqueta creada: '),
|
|
47
46
|
label_warn: t('⚠️ Failed to create label (might already exist): ', '⚠️ Falha ao criar label (talvez já exista): ', '⚠️ Fallo al crear etiqueta (quizás ya exista): '),
|
|
48
|
-
applying_protection: t('[2/3] Applying branch protection on ', '[2/3] Aplicando proteção de branch em ', '[2/3] Aplicando protección de rama en '),
|
|
49
|
-
protection_ok: t('✅ Branch protection applied to ', '✅ Proteção de branch aplicada em ', '✅ Protección de rama aplicada a '),
|
|
50
|
-
protection_warn: t('⚠️ Failed to apply branch protection. (Do you have GitHub Pro or is the repo Public?)', '⚠️ Falha ao aplicar proteção de branch. (Você tem GitHub Pro ou o repo é Público?)', '⚠️ Fallo al aplicar protección de rama. (¿Tienes GitHub Pro o el repositorio es Público?)'),
|
|
51
47
|
creating_project: t('[2/2] Creating Project V2 Board...', '[2/2] Criando Project V2 Board...', '[2/2] Creando Project V2 Board...'),
|
|
52
48
|
project_ok: t('✅ Project created (ID: ', '✅ Projeto criado (ID: ', '✅ Proyecto creado (ID: '),
|
|
53
49
|
project_err: t('❌ Failed to create project. Error: ', '❌ Falha ao criar o projeto. Erro: ', '❌ Fallo al crear el proyecto. Error: '),
|
|
@@ -60,19 +56,8 @@ const i18n = {
|
|
|
60
56
|
templates_copied: t('✅ Templates copied to .agentic-pdlc/templates/', '✅ Templates copiados para .agentic-pdlc/templates/', '✅ Plantillas copiadas a .agentic-pdlc/templates/'),
|
|
61
57
|
pdlc_prefilled: t('✅ Pre-filled pdlc.md with Project ID, Status Field ID, and Column Option IDs.', '✅ pdlc.md preenchido com Project ID, Status Field ID, e Column Option IDs.', '✅ pdlc.md completado con Project ID, Status Field ID y Column Option IDs.'),
|
|
62
58
|
setup_written: t('✅ Setup agent profile written to .agentic-setup.md\n', '✅ Perfil de setup do agente salvo em .agentic-setup.md\n', '✅ Perfil de configuración del agente guardado en .agentic-setup.md\n'),
|
|
63
|
-
framework_scaffolded: t('🎉 Framework files scaffolded to .agentic-pdlc/templates/', '🎉 Arquivos do framework injetados em .agentic-pdlc/templates/', '🎉 Archivos del framework inyectados en .agentic-pdlc/templates/'),
|
|
64
|
-
next_steps: t('👉 NEXT STEPS:', '👉 PRÓXIMOS PASSOS:', '👉 PRÓXIMOS PASOS:'),
|
|
65
|
-
step_1: t('1. Open your AI Assistant (Claude, Cursor, Copilot, etc).', '1. Abra o seu Assistente de IA (Claude, Cursor, Copilot, etc).', '1. Abre tu Asistente de IA (Claude, Cursor, Copilot, etc).'),
|
|
66
|
-
step_2: t('2. Ask it to read the .agentic-setup.md and start Setup Mode in any language you prefer. Example 👇', '2. Peça para ele ler o .agentic-setup.md e iniciar o Setup Mode. Exemplo 👇', '2. Pídele que lea .agentic-setup.md e inicie el Setup Mode. Ejemplo 👇'),
|
|
67
|
-
note_cleanup: t('Note: The agent will clean up the .agentic-setup.md file automatically when finished.\n', 'Nota: O agente irá limpar o arquivo .agentic-setup.md automaticamente quando terminar.\n', 'Nota: El agente limpiará el archivo .agentic-setup.md automáticamente cuando termine.\n'),
|
|
68
59
|
missing_claude: t('❌ Could not find instruction file at ', '❌ Não foi possível encontrar o arquivo de instrução em ', '❌ No se pudo encontrar el archivo de instrucción en '),
|
|
69
60
|
cursor_rules_written: t('✅ Default cursor rules written to .cursorrules', '✅ Regras padrão do cursor salvas em .cursorrules', '✅ Reglas por defecto de cursor guardadas en .cursorrules'),
|
|
70
|
-
cursor_setup_written: t('✅ Framework Setup Instructions written to .agentic-pdlc/SETUP_PROMPT.md', '✅ Instruções de Setup do Framework salvas em .agentic-pdlc/SETUP_PROMPT.md', '✅ Instrucciones de Setup del Framework guardadas en .agentic-pdlc/SETUP_PROMPT.md'),
|
|
71
|
-
cursor_done: t('🎉 Done! To start the conversational setup:', '🎉 Pronto! Para iniciar o setup conversacional:', '🎉 ¡Listo! Para iniciar la configuración conversacional:'),
|
|
72
|
-
cursor_step_1: t('\t1. Open Cursor', '\t1. Abra o Cursor', '\t1. Abre Cursor'),
|
|
73
|
-
cursor_step_2: t('\t2. Open Composer (Cmd+I or Cmd+L) and type: "@.agentic-pdlc/SETUP_PROMPT.md execute Setup Mode"\n', '\t2. Abra o Composer (Cmd+I ou Cmd+L) e digite: "@.agentic-pdlc/SETUP_PROMPT.md execute Setup Mode"\n', '\t2. Abre Composer (Cmd+I o Cmd+L) y escribe: "@.agentic-pdlc/SETUP_PROMPT.md execute Setup Mode"\n'),
|
|
74
|
-
generic_written: t('✅ Agent generic setup instructions written to .agentic-setup.md', '✅ Instruções genéricas salvas em .agentic-setup.md', '✅ Instrucciones genéricas guardadas en .agentic-setup.md'),
|
|
75
|
-
generic_done: t('Tell your AI agent to read and execute the .agentic-setup.md file!\n', 'Diga ao seu agente para ler e executar o arquivo .agentic-setup.md!\n', '¡Dile a tu agente de IA que lea y ejecute el archivo .agentic-setup.md!\n'),
|
|
76
61
|
setup_done: t('🎉 All set! Continue the setup with your agent:', '🎉 Aqui tá pronto! Continue o setup com o seu agente:', '🎉 ¡Listo! Continúa el setup con tu agente:'),
|
|
77
62
|
setup_done_hint: t('>>> Tell it to read and execute the .agentic-setup.md file!', '>>> Diga a ele para ler e executar o arquivo .agentic-setup.md!', '>>> Dile que lea y ejecute el archivo .agentic-setup.md!')
|
|
78
63
|
};
|
|
@@ -159,14 +144,6 @@ async function runSetup() {
|
|
|
159
144
|
isOrg = accountTypeAnswer.trim().toLowerCase() === 'org' || accountTypeAnswer.trim().toLowerCase() === 'organization';
|
|
160
145
|
}
|
|
161
146
|
|
|
162
|
-
let branchName = 'main';
|
|
163
|
-
try {
|
|
164
|
-
branchName = execFileSync('gh', ['api', `repos/${repo}`, '--jq', '.default_branch'], { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim() || 'main';
|
|
165
|
-
} catch (err) {
|
|
166
|
-
const branchAnswer = await askQuestion(i18n.ask_branch);
|
|
167
|
-
if (branchAnswer.trim()) branchName = branchAnswer.trim();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
147
|
console.log(`\n${yellow}${i18n.starting_setup}${reset}`);
|
|
171
148
|
|
|
172
149
|
// Labels
|
|
@@ -197,7 +174,7 @@ async function runSetup() {
|
|
|
197
174
|
|
|
198
175
|
// Project V2
|
|
199
176
|
console.log(`\n${cyan}${i18n.creating_project}${reset}`);
|
|
200
|
-
let ownerId, projectId;
|
|
177
|
+
let ownerId, projectId, projectNumber;
|
|
201
178
|
try {
|
|
202
179
|
if (isOrg) {
|
|
203
180
|
const orgOutput = execFileSync('gh', ['api', 'graphql', '-f', 'query=query($login: String!) { organization(login: $login) { id } }', '-f', `login=${repoOwner}`, '--jq', '.data.organization.id']).toString().trim();
|
|
@@ -207,8 +184,14 @@ async function runSetup() {
|
|
|
207
184
|
ownerId = userOutput;
|
|
208
185
|
}
|
|
209
186
|
|
|
210
|
-
const
|
|
211
|
-
|
|
187
|
+
const projectCreateRaw = execFileSync('gh', ['api', 'graphql', '-f', 'query=mutation($owner: ID!, $title: String!) { createProjectV2(input: {ownerId: $owner, title: $title}) { projectV2 { id number } } }', '-f', `owner=${ownerId}`, '-f', `title=${boardName}`]).toString().trim();
|
|
188
|
+
const projectCreateResponse = JSON.parse(projectCreateRaw);
|
|
189
|
+
if (projectCreateResponse.errors) {
|
|
190
|
+
throw new Error(projectCreateResponse.errors.map(e => e.message).join('; '));
|
|
191
|
+
}
|
|
192
|
+
const projectCreateData = projectCreateResponse.data.createProjectV2.projectV2;
|
|
193
|
+
projectId = projectCreateData.id;
|
|
194
|
+
projectNumber = projectCreateData.number;
|
|
212
195
|
|
|
213
196
|
console.log(` ${i18n.project_ok}${projectId})`);
|
|
214
197
|
|
|
@@ -317,12 +300,32 @@ async function runSetup() {
|
|
|
317
300
|
fs.writeFileSync(pdlcDest, pdlcContent);
|
|
318
301
|
console.log(`${i18n.pdlc_prefilled}`);
|
|
319
302
|
}
|
|
303
|
+
|
|
304
|
+
// Pre-fill project-automation.yml with the same IDs so the agent doesn't need to map them
|
|
305
|
+
const workflowAutomationPath = path.join(targetTemplates, '.github', 'workflows', 'project-automation.yml');
|
|
306
|
+
if (fs.existsSync(workflowAutomationPath)) {
|
|
307
|
+
let wfContent = fs.readFileSync(workflowAutomationPath, 'utf8');
|
|
308
|
+
if (projectId) wfContent = wfContent.replace(/\{\{PROJECT_ID\}\}/g, () => projectId);
|
|
309
|
+
if (statusFieldId) wfContent = wfContent.replace(/\{\{STATUS_FIELD_ID\}\}/g, () => statusFieldId);
|
|
310
|
+
if (Object.keys(optionMap).length > 0) {
|
|
311
|
+
wfContent = wfContent.replace(/\{\{ID_IDEA\}\}/g, optionMap["💡 Idea"] || 'MISSING_ID');
|
|
312
|
+
wfContent = wfContent.replace(/\{\{ID_EXPLORATION\}\}/g, () => optionMap["🔍 Exploration"] || 'MISSING_ID');
|
|
313
|
+
wfContent = wfContent.replace(/\{\{ID_BRAINSTORMING\}\}/g, () => optionMap["🧠 Brainstorming"] || 'MISSING_ID');
|
|
314
|
+
wfContent = wfContent.replace(/\{\{ID_DETAILING\}\}/g, () => optionMap["📐 Detail Solution"] || 'MISSING_ID');
|
|
315
|
+
wfContent = wfContent.replace(/\{\{ID_APPROVAL\}\}/g, () => optionMap["✅ Approval"] || 'MISSING_ID');
|
|
316
|
+
wfContent = wfContent.replace(/\{\{ID_DEVELOPMENT\}\}/g, () => optionMap["⚙️ Development"] || 'MISSING_ID');
|
|
317
|
+
wfContent = wfContent.replace(/\{\{ID_TESTING\}\}/g, () => optionMap["🧪 Testing"] || 'MISSING_ID');
|
|
318
|
+
wfContent = wfContent.replace(/\{\{ID_CODE_REVIEW_PR\}\}/g, () => optionMap["👁 Code Review / PR"] || 'MISSING_ID');
|
|
319
|
+
wfContent = wfContent.replace(/\{\{ID_PRODUCTION\}\}/g, () => optionMap["🚀 Ready for Production"] || 'MISSING_ID');
|
|
320
|
+
}
|
|
321
|
+
fs.writeFileSync(workflowAutomationPath, wfContent);
|
|
322
|
+
}
|
|
320
323
|
}
|
|
321
324
|
|
|
322
325
|
// Write CLI context for the agent to consume in Setup Mode
|
|
323
326
|
try {
|
|
324
327
|
const cliContextPath = path.join(targetDir, '.agentic-pdlc', 'cli-context.json');
|
|
325
|
-
fs.writeFileSync(cliContextPath, JSON.stringify({ projectName, repoOwner, repoName }, null, 2));
|
|
328
|
+
fs.writeFileSync(cliContextPath, JSON.stringify({ projectName, repoOwner, repoName, projectNumber }, null, 2));
|
|
326
329
|
} catch (err) {
|
|
327
330
|
// Non-fatal — agent will ask for the values instead
|
|
328
331
|
}
|
|
@@ -342,26 +345,28 @@ async function runSetup() {
|
|
|
342
345
|
}
|
|
343
346
|
} else if (agent === 'cursor') {
|
|
344
347
|
if (fs.existsSync(cursorSetupSrc)) {
|
|
345
|
-
// Create .cursorrules which has the general invariants
|
|
346
348
|
const dest = path.join(targetDir, '.cursorrules');
|
|
347
349
|
fs.copyFileSync(cursorSetupSrc, dest);
|
|
348
|
-
|
|
349
|
-
// Also copy skill.md as a setup prompt for cursor composer
|
|
350
|
-
const setupPromptDest = path.join(targetDir, '.agentic-pdlc', 'SETUP_PROMPT.md');
|
|
351
|
-
if (fs.existsSync(claudeSetupSrc)) fs.copyFileSync(claudeSetupSrc, setupPromptDest);
|
|
352
|
-
|
|
353
350
|
console.log(`${i18n.cursor_rules_written}`);
|
|
354
|
-
|
|
351
|
+
|
|
352
|
+
if (fs.existsSync(claudeSetupSrc)) {
|
|
353
|
+
const setupDest = path.join(targetDir, '.agentic-setup.md');
|
|
354
|
+
fs.copyFileSync(claudeSetupSrc, setupDest);
|
|
355
|
+
console.log(`${i18n.setup_written}`);
|
|
356
|
+
}
|
|
355
357
|
printSetupDone();
|
|
356
358
|
} else {
|
|
357
359
|
console.error(`${i18n.missing_claude}${cursorSetupSrc}`);
|
|
358
360
|
}
|
|
359
361
|
} else {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
362
|
+
if (fs.existsSync(claudeSetupSrc)) {
|
|
363
|
+
const dest = path.join(targetDir, '.agentic-setup.md');
|
|
364
|
+
fs.copyFileSync(claudeSetupSrc, dest);
|
|
365
|
+
console.log(`${i18n.setup_written}`);
|
|
366
|
+
printSetupDone();
|
|
367
|
+
} else {
|
|
368
|
+
console.error(`${i18n.missing_claude}${claudeSetupSrc}`);
|
|
369
|
+
}
|
|
365
370
|
}
|
|
366
371
|
|
|
367
372
|
rl.close();
|
package/package.json
CHANGED
|
@@ -16,14 +16,12 @@ jobs:
|
|
|
16
16
|
issues: write
|
|
17
17
|
pull-requests: write
|
|
18
18
|
contents: read
|
|
19
|
-
env:
|
|
20
|
-
PROJECT_TOKEN: ${{ secrets.PROJECT_TOKEN }}
|
|
21
19
|
steps:
|
|
22
20
|
- name: Update Labels
|
|
23
|
-
if: ${{
|
|
21
|
+
if: ${{ !contains('{{IMPLEMENTATION_AGENT_LABEL}}', '{{') }}
|
|
24
22
|
uses: actions/github-script@v7
|
|
25
23
|
with:
|
|
26
|
-
github-token: ${{
|
|
24
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
27
25
|
script: |
|
|
28
26
|
const { owner, repo } = context.repo;
|
|
29
27
|
const issue_number = context.payload.issue.number;
|
|
@@ -28,13 +28,13 @@ jobs:
|
|
|
28
28
|
if: github.event_name == 'issues' && github.event.action == 'labeled'
|
|
29
29
|
runs-on: ubuntu-latest
|
|
30
30
|
env:
|
|
31
|
-
|
|
31
|
+
PROJECT_PAT: ${{ secrets.PROJECT_PAT }}
|
|
32
32
|
steps:
|
|
33
33
|
- name: Detect Label and Move Issue
|
|
34
|
-
if: ${{ env.
|
|
34
|
+
if: ${{ env.PROJECT_PAT != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
35
35
|
uses: actions/github-script@v7
|
|
36
36
|
with:
|
|
37
|
-
github-token: ${{ env.
|
|
37
|
+
github-token: ${{ env.PROJECT_PAT }}
|
|
38
38
|
script: |
|
|
39
39
|
const labelName = context.payload.label.name;
|
|
40
40
|
let targetStatusId = null;
|
|
@@ -94,10 +94,10 @@ jobs:
|
|
|
94
94
|
# runs-on: ubuntu-latest
|
|
95
95
|
# steps:
|
|
96
96
|
# - name: Move issue to Idea
|
|
97
|
-
# if: ${{ env.
|
|
97
|
+
# if: ${{ env.PROJECT_PAT != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
98
98
|
# uses: actions/github-script@v7
|
|
99
99
|
# with:
|
|
100
|
-
# github-token: ${{ env.
|
|
100
|
+
# github-token: ${{ env.PROJECT_PAT }}
|
|
101
101
|
# script: |
|
|
102
102
|
# const { issue: { number, node_id } } = context.payload;
|
|
103
103
|
# const { addProjectV2ItemById: { item } } = await github.graphql(`
|
|
@@ -122,13 +122,13 @@ jobs:
|
|
|
122
122
|
if: github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened')
|
|
123
123
|
runs-on: ubuntu-latest
|
|
124
124
|
env:
|
|
125
|
-
|
|
125
|
+
PROJECT_PAT: ${{ secrets.PROJECT_PAT }}
|
|
126
126
|
steps:
|
|
127
127
|
- name: Move linked issue to Code Review / PR
|
|
128
|
-
if: ${{ env.
|
|
128
|
+
if: ${{ env.PROJECT_PAT != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
129
129
|
uses: actions/github-script@v7
|
|
130
130
|
with:
|
|
131
|
-
github-token: ${{ env.
|
|
131
|
+
github-token: ${{ env.PROJECT_PAT }}
|
|
132
132
|
script: |
|
|
133
133
|
const prNumber = context.payload.pull_request.number;
|
|
134
134
|
const { owner, repo } = context.repo;
|
|
@@ -176,13 +176,13 @@ jobs:
|
|
|
176
176
|
if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved'
|
|
177
177
|
runs-on: ubuntu-latest
|
|
178
178
|
env:
|
|
179
|
-
|
|
179
|
+
PROJECT_PAT: ${{ secrets.PROJECT_PAT }}
|
|
180
180
|
steps:
|
|
181
181
|
- name: Swap PR labels
|
|
182
|
-
if: ${{ env.
|
|
182
|
+
if: ${{ env.PROJECT_PAT != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
183
183
|
uses: actions/github-script@v7
|
|
184
184
|
with:
|
|
185
|
-
github-token: ${{ env.
|
|
185
|
+
github-token: ${{ env.PROJECT_PAT }}
|
|
186
186
|
script: |
|
|
187
187
|
const prNumber = context.payload.pull_request.number;
|
|
188
188
|
const { owner, repo } = context.repo;
|
|
@@ -195,13 +195,13 @@ jobs:
|
|
|
195
195
|
if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
|
|
196
196
|
runs-on: ubuntu-latest
|
|
197
197
|
env:
|
|
198
|
-
|
|
198
|
+
PROJECT_PAT: ${{ secrets.PROJECT_PAT }}
|
|
199
199
|
steps:
|
|
200
200
|
- name: Move issue to Production
|
|
201
|
-
if: ${{ env.
|
|
201
|
+
if: ${{ env.PROJECT_PAT != '' && env.PROJECT_ID != '{{PROJECT_ID}}' }}
|
|
202
202
|
uses: actions/github-script@v7
|
|
203
203
|
with:
|
|
204
|
-
github-token: ${{ env.
|
|
204
|
+
github-token: ${{ env.PROJECT_PAT }}
|
|
205
205
|
script: |
|
|
206
206
|
const prNumber = context.payload.pull_request.number;
|
|
207
207
|
const { owner, repo } = context.repo;
|