Mauvais héritage des propriétés passées à DsfrTag par DsfrTags #579
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: Check PR linked to issue | |
| on: | |
| pull_request: | |
| types: [opened, edited, synchronize, reopened, ready_for_review] | |
| # Relancer quand une issue est fermée/ouverte (peut affecter les liaisons) | |
| issues: | |
| types: [opened, closed, reopened] | |
| jobs: | |
| check-linked-issue: | |
| runs-on: ubuntu-latest | |
| # Exception : les PR de develop vers main n'ont pas besoin d'être liées à une issue | |
| if: (github.event_name == 'pull_request' && (github.head_ref != 'develop' || | |
| github.base_ref != 'main')) || github.event_name == 'issues' | |
| steps: | |
| - name: Check if PR is linked to an issue | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| let pullRequests = []; | |
| if (context.eventName === 'issues') { | |
| // Si l'événement vient d'une issue, vérifier toutes les PR ouvertes | |
| const { data: prs } = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open' | |
| }); | |
| pullRequests = prs.filter(pr => pr.head.ref !== 'develop' || pr.base.ref !== 'main'); | |
| } else { | |
| // Événement normal de PR | |
| const { data: pullRequest } = await github.rest.pulls.get({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.issue.number, | |
| }); | |
| pullRequests = [pullRequest]; | |
| } | |
| for (const pullRequest of pullRequests) { | |
| console.log(`🔍 Vérification de la PR #${pullRequest.number}: ${pullRequest.title}`); | |
| // Vérifier les issues liées via l'interface GitHub avec GraphQL | |
| const query = ` | |
| query($owner: String!, $repo: String!, $number: Int!) { | |
| repository(owner: $owner, name: $repo) { | |
| pullRequest(number: $number) { | |
| closingIssuesReferences(first: 50) { | |
| nodes { | |
| number | |
| title | |
| } | |
| } | |
| } | |
| } | |
| } | |
| `; | |
| let linkedIssuesFromUI = []; | |
| try { | |
| const result = await github.graphql(query, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| number: pullRequest.number, | |
| }); | |
| linkedIssuesFromUI = result.repository.pullRequest.closingIssuesReferences.nodes; | |
| } catch (error) { | |
| console.log('Erreur lors de la récupération des issues liées via GraphQL:', error.message); | |
| } | |
| // Vérifier dans le corps de la PR (mots-clés comme "closes #123", "fixes #456") | |
| const prBody = pullRequest.body || ''; | |
| const prTitle = pullRequest.title || ''; | |
| // Pattern pour détecter les références aux issues | |
| const issueKeywords = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?|ref(?:erences?)?|see|relate[sd]?(?:\s+to)?)\s*(?:#(\d+)|https?:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/(\d+))/gi; | |
| const bodyMatches = prBody.match(issueKeywords); | |
| const titleMatches = prTitle.match(issueKeywords); | |
| // Vérifier aussi les numéros d'issues simples dans le titre (ex: "feat: #123 - nouvelle fonctionnalité") | |
| const simpleIssueRef = /(?:^|\s)#(\d+)(?:\s|$|-)/g; | |
| const titleIssueRefs = prTitle.match(simpleIssueRef); | |
| const hasLinkedIssues = linkedIssuesFromUI.length > 0 || bodyMatches || titleMatches || titleIssueRefs; | |
| if (!hasLinkedIssues) { | |
| core.setFailed(`❌ La PR #${pullRequest.number} doit être liée à une issue. Utilisez des mots-clés comme "closes #123" ou "fixes #456" dans la description, référencez une issue dans le titre avec "#123", ou liez une issue via l'interface GitHub.`); | |
| break; // Arrêter au premier échec | |
| } else { | |
| console.log(`✅ PR #${pullRequest.number} correctement liée à une ou plusieurs issues`); | |
| if (linkedIssuesFromUI.length > 0) { | |
| console.log('Issues liées via l\'interface GitHub:', linkedIssuesFromUI.map(issue => `#${issue.number} - ${issue.title}`)); | |
| } | |
| if (bodyMatches) console.log('Issues trouvées dans le body:', bodyMatches); | |
| if (titleMatches) console.log('Issues trouvées dans le titre:', titleMatches); | |
| if (titleIssueRefs) console.log('Références d\'issues dans le titre:', titleIssueRefs); | |
| } | |
| } |