Skip to content

Mauvais héritage des propriétés passées à DsfrTag par DsfrTags #579

Mauvais héritage des propriétés passées à DsfrTag par DsfrTags

Mauvais héritage des propriétés passées à DsfrTag par DsfrTags #579

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);
}
}