chore(deps): update docker.elastic.co/elasticsearch/elasticsearch docker tag to v9.3.4 #4715
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Assign PRs to GitHub Projects V2 | |
| on: | |
| pull_request: | |
| types: [opened, reopened, labeled, unlabeled, synchronize] | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "Ne rien modifier, seulement logguer" | |
| required: false | |
| type: boolean | |
| default: false | |
| env: | |
| PROJECT_ID_MAPPING: | | |
| squad:pmo=PVT_kwDOBOJOp84A8tDc | |
| squad:ux=PVT_kwDOBOJOp84A2ZQ8 | |
| squad:backend=PVT_kwDOBOJOp84A2ZRZ | |
| squad:platform=PVT_kwDOBOJOp84BB-GS | |
| IF_UNMATCH: PVT_kwDOBOJOp84A8tDc | |
| # Laisser vide pour ne filtrer par auteur | |
| FILTER_AUTHOR: "renovate[bot]" | |
| jobs: | |
| assign: | |
| if: > | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'pull_request' && | |
| github.event.pull_request.user.login == 'renovate[bot]') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Assign PRs to Projects | |
| uses: actions/github-script@v9 | |
| with: | |
| github-token: ${{ secrets.PROJECT_PAT }} | |
| script: | | |
| const mapping = Object.fromEntries( | |
| (process.env.PROJECT_ID_MAPPING || '') | |
| .split('\n') | |
| .map(l => l.trim().split('=')) | |
| .filter(parts => parts.length === 2) | |
| .map(([k, v]) => [k.toLowerCase(), v.trim()]) | |
| ); | |
| const fallback = (process.env.IF_UNMATCH || '').trim(); | |
| const filterAuthor = (process.env.FILTER_AUTHOR || '').trim(); | |
| const dryRun = core.getInput('dry_run') === 'true'; | |
| // --- Validation des ProjectV2 IDs --- | |
| const allIds = Array.from( | |
| new Set([ ...Object.values(mapping), fallback ].filter(Boolean)) | |
| ); | |
| if (allIds.length) { | |
| const res = await github.graphql( | |
| `query($ids:[ID!]!){ nodes(ids:$ids){ __typename }}`, { ids: allIds } | |
| ); | |
| const invalid = allIds.filter((id, i) => res.nodes[i]?.__typename !== 'ProjectV2'); | |
| if (invalid.length) { | |
| core.setFailed('Project IDs introuvables: ' + invalid.join(', ')); | |
| return; | |
| } | |
| } | |
| // --- Helpers GraphQL --- | |
| async function getItems(nodeId) { | |
| const q = ` | |
| query($id:ID!){ node(id:$id){ ... on PullRequest { | |
| projectItems(first:100){ nodes{id project{id}} } | |
| }}}`; | |
| const r = await github.graphql(q, { id: nodeId }); | |
| return r.node.projectItems.nodes.map(n => ({ | |
| itemId: n.id, | |
| projectId: n.project.id | |
| })); | |
| } | |
| async function addItem(nodeId, projId) { | |
| const m = ` | |
| mutation($projId:ID!,$cntId:ID!){ | |
| addProjectV2ItemById(input:{projectId:$projId,contentId:$cntId}) { | |
| item{id} | |
| } | |
| }`; | |
| await github.graphql(m, { projId, cntId: nodeId }); | |
| } | |
| async function removeItem(itemId, projId) { | |
| const m = ` | |
| mutation($projId:ID!,$itmId:ID!){ | |
| deleteProjectV2Item(input:{projectId:$projId,itemId:$itmId}) { | |
| deletedItemId | |
| } | |
| }`; | |
| await github.graphql(m, { projId, itmId: itemId }); | |
| } | |
| // --- Calcul des projets cibles --- | |
| function pickProjects(labels) { | |
| const s = new Set(); | |
| labels.forEach(l => { | |
| const key = l.toLowerCase(); | |
| if (mapping[key]) s.add(mapping[key]); | |
| }); | |
| if (!s.size && fallback) s.add(fallback); | |
| return Array.from(s); | |
| } | |
| // --- Construction de la liste des PR à traiter --- | |
| let prNumbers = []; | |
| if (context.eventName === 'workflow_dispatch') { | |
| let page = 1; | |
| while (true) { | |
| const list = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| per_page: 100, | |
| page | |
| }); | |
| if (!list.data.length) break; | |
| prNumbers.push(...list.data.map(p => p.number)); | |
| page++; | |
| } | |
| } else { | |
| prNumbers = [ context.payload.pull_request.number ]; | |
| } | |
| core.info('Processing ' + prNumbers.length + ' PR(s)'); | |
| // --- Traitement de chaque PR --- | |
| for (const num of prNumbers) { | |
| core.startGroup('PR #' + num); | |
| // Récupération de la PR | |
| const pr = (context.eventName === 'workflow_dispatch') | |
| ? (await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: num | |
| })).data | |
| : context.payload.pull_request; | |
| // Filtre sur l’auteur (uniquement si FILTER_AUTHOR est non vide) | |
| if (filterAuthor !== '' && pr.user.login !== filterAuthor) { | |
| core.info('Auteur ignoré: ' + pr.user.login); | |
| core.endGroup(); | |
| continue; | |
| } | |
| // Labels | |
| const labels = pr.labels | |
| .map(l => typeof l === 'string' ? l : l.name) | |
| .map(n => n.toLowerCase()); | |
| core.info('Labels: ' + (labels.length ? labels.join(', ') : '(none)')); | |
| // Différences | |
| const desired = pickProjects(labels); | |
| const existing = await getItems(pr.node_id); | |
| const existIds = existing.map(e => e.projectId); | |
| const toAdd = desired.filter(id => !existIds.includes(id)); | |
| const toRemove = existing.filter(e => !desired.includes(e.projectId)); | |
| core.info('To add: ' + (toAdd .length ? toAdd .join(', ') : '(none)')); | |
| core.info('To remove: ' + (toRemove.length ? toRemove.map(e => e.projectId).join(', ') : '(none)')); | |
| // Application des changements | |
| if (!dryRun) { | |
| for (const id of toAdd) { | |
| try { await addItem(pr.node_id, id); core.info('Added to ' + id); } | |
| catch(e){ core.error('Add error ' + id + ': ' + e.message); } | |
| } | |
| for (const { itemId, projectId } of toRemove) { | |
| try { await removeItem(itemId, projectId); core.info('Removed from ' + projectId); } | |
| catch(e){ core.error('Remove error ' + projectId + ': ' + e.message); } | |
| } | |
| } else { | |
| core.info('[DRY RUN] No changes'); | |
| } | |
| core.endGroup(); | |
| } |