Maximize Page
Tech & DevOps HubEspace Tech & DevOps: Explorez le monde du Dev, du Cloud et des outils DevOps à travers nos articles et discussions Explore the world of development, the cloud and DevOps tools

Script PowerShell pour le nettoyage des exécutions GitHub Actions

Date de l'article:06-09-2026
CI/CD Github-Actions
Très utile lorsque le nombre d'exécutions GitHub Actions devient important, ce script permet de nettoyer automatiquement l'historique en conservant uniquement le nombre d'exécutions souhaité.
Des workflows encombrés et pas le temps de nettoyer ?
Lorsqu'on démarre un nouveau projet avec une chaîne CI/CD, de nombreux workflows peuvent s'exécuter sans que l'on prête immédiatement attention au nombre d'exécutions accumulées. On se retrouve rapidement avec plusieurs centaines, voire plusieurs milliers de runs (800, 1 000 ou davantage).
Dans cet article, nous allons mettre en place un script PowerShell permettant de nettoyer automatiquement l'historique des exécutions GitHub Actions.
Pour limiter l'accumulation des données générées par GitHub Actions et éviter d'atteindre les limites de stockage, plusieurs stratégies sont possibles:
1. Configurer la durée de rétention des artifacts et des logs au niveau du dépôt ou de l'organisation
2. Définir une durée de rétention spécifique lors de l'upload d'un artifact dans un workflow, avec l'option "retention-days" de l'action "actions/upload-artifact"
source: how-long-are-github-actions-artifacts-kept
3. Supprimer automatiquement les anciens workflow runs à l'aide de l'API GitHub ou d'une GitHub Action dédiée.
Exemple: Delete Artifacts ou Remove Artifacts
Ajuster la durée de rétention par défaut (Global)
Au niveau du dépôt:
Settings → Actions → General, section "Artifact and log retention"
artifacts logs retention
Par défaut, GitHub conserve les artifacts pendant 90 jours
Vous pouvez notamment réduire cette durée jusqu'à 1 jour directement depuis l'interface
Cette configuration concerne la durée de conservation des artifacts et des logs.
Elle ne supprime pas directement les workflow runs existants selon le nombre d'exécutions à conserver: c'est précisément ce que nous allons automatiser avec le script présenté dans cet article.

Mise en place
1. Créer le token dedié
Si vous n'en avez pas encore:
Depuis votre photo de profil, ouvrez Settings → Developer Settings
Cliquez sur : Personal Access Token
Puis, sélectionnez "Fine-grained tokens"
GitHub versionne son API REST à l'aide de versions identifiées par une date.
La version stable actuelle à utiliser est l'apiVersion=2026-03-10
2. Lui donner les permissions
Repository access:
Limitez le token au dépôt concerné lorsque cela est possible
Repository Permission:
Actions → Read access to Metadata
Actions → Read and Write access to code and pull request

Tester le token
Il est recommandé de préciser explicitement la version utilisée dans les requêtes afin de conserver un comportement prévisible.
Au moment de la rédaction, j'utilise la version 2026-03-10. Vérifiez la version recommandée dans la documentation avant de reprendre cet exemple.
Cette première commande permet simplement de vérifier que le token est accepté par l'API GitHub
via PowerShell
$token = "github_pat_xxxxxxxxxxxxxxxxxxxxxxxxxx"
curl --request GET --url "https://api.github.com/octocat" --header "Authorization: Bearer $token" --header "X-GitHub-Api-Version: 2026-03-10"
Adapter à votre token et lancer la commande curl
#output: connexion ok
               MMM.           .MMM
               MMMMMMMMMMMMMMMMMMM
               MMMMMMMMMMMMMMMMMMM      _________________________________________
              MMMMMMMMMMMMMMMMMMMMM    |                                         |
             MMMMMMMMMMMMMMMMMMMMMMM   | Anything added dilutes everything else. |
            MMMMMMMMMMMMMMMMMMMMMMMM   |_   _____________________________________|
            MMMM::- -:::::::- -::MMMM    |/
             MM~:~ 00~:::::~ 00~:~MM
        .. MMMMM::.00:::+:::.00::MMMMM ..
              .MM::::: ._. :::::MM.
                 MMMM;:::::;MMMM
          -MM        MMMMMMM
          ^  M+     MMMMMMMMM
              MMMMMMM MM MM MM
                   MM MM MM MM
                   MM MM MM MM
                .~~MM~MM~MM~MM~~.
             ~~~~MM:~MM~~~MM~:MM~~~~
            ~~~~~~==~==~~~==~==~~~~~~
             ~~~~~~==~==~==~==~~~~~~
                 :~==~==~==~==~~  
ou un message d'erreur:
#output: connexion failed
curl --request GET --url "https://api.github.com/octocat" --header "Authorization: Bearer ...

{
  "message": "Bad credentials",
  "documentation_url": "https://docs.github.com/rest",
  "status": "401"
}
Un retour HTTP 200 confirme que le token est valide, mais ne garantit pas qu'il dispose des permissions nécessaires pour supprimer des workflow runs. Ces permissions seront réellement vérifiées lors de l'appel à l'API concerné.

Écriture du script
1. Dans PowerShell, depuis n'importe quel emplacement:
mkdir Temp
cd C:\Temp
notepad cleanup-github-runs.ps1
Le script permet de nettoyer automatiquement l'historique des exécutions GitHub Actions d'un dépôt donné. Il récupère les workflow runs, les trie du plus récent au plus ancien, puis supprime ceux qui dépassent le nombre d'exécutions à conserver.
2. Dans notepad, copier le script, replacer le token, enregistrer
$token = "github_pat_xxxxxxxxxxxxxxxxxxxxxxxxxx"
$owner = "USER_NAME"
$repo = "REPO_NAME"
$keep = 100

$headers = @{
    Authorization = "Bearer $token"
    Accept = "application/vnd.github+json"
    "X-GitHub-Api-Version" = "2026-03-10"
}

$page = 1
$runs = @()

do {
    $response = Invoke-RestMethod `
        -Uri "https://api.github.com/repos/$owner/$repo/actions/runs?per_page=100&page=$page" `
        -Headers $headers

    $runs += $response.workflow_runs
    $page++
}
while ($response.workflow_runs.Count -gt 0)

Write-Host "Total runs found: $($runs.Count)"

$toDelete = $runs | Sort-Object created_at -Descending | Select-Object -Skip $keep

Write-Host "Deleting $($toDelete.Count) old runs..."

foreach ($run in $toDelete) {
    Write-Host "Deleting run $($run.id) - $($run.name)"
    Invoke-RestMethod `
        -Method Delete `
        -Uri "https://api.github.com/repos/$owner/$repo/actions/runs/$($run.id)" `
        -Headers $headers
}

Write-Host "Done!"

Résumé des étapes

Définition des variables d'accès:
  • La clé de sécurité ($token)
  • Le nom du compte ($owner) et du projet ($repo)
  • Le nombre de workflow runs à conserver ($keep = 100)

Pour que GitHub accepte la requête, on envoie ces autorisations via le $headers
La collecte de l'historique
Le script interroge l'API REST GitHub afin de récupérer les workflow runs du dépôt.
L'API renvoie les résultats par pages, avec jusqu'à 100 éléments par requête. Le script parcourt donc les différentes pages jusqu'à avoir récupéré l'ensemble des résultats disponibles.
Le tri et le ciblage
On affiche ensuite le nombre total de runs trouvés.
Le script trie ensuite les workflow runs par date de création, du plus récent au plus ancien :
$runs | Sort-Object created_at -Descending
Puis Select-Object -Skip $keep ignore les premiers éléments et place tous les suivants dans $toDelete
La suppression
Avec la -Method Delete, le script parcourt la liste des anciens éléments et, pour chacun il envoie un ordre d'effacement définitif à GitHub

Avant de lancer le nettoyage complet, il est préférable d'effectuer un petit test afin de vérifier le comportement du script. Ainsi, en cas de problème, le nombre d'exécutions supprimées reste limité.

Test et validation du script
Premier test (de précaution)
Contexte: J'ai 838 runs et, pour le premier lancement de script:
On va remplacer temporairement:
$keep = 100 par: $keep = 830
De cette manière on peut vérifier que tout fonctionne correctement.
Cette opération est destructive: une fois les workflow runs supprimés, ils ne sont plus disponibles dans l'historique du dépôt. Il est donc recommandé de tester le script avec une valeur élevée de $keep avant de lancer le nettoyage complet.
Lancer le script, (depuis C:\Temp) avec:
.\cleanup-github-runs.ps1
#output
Total runs found: 838
Deleting 8 old runs...
Le script à bien supprimé 8 runs

Exécution du script
Ensuite, on remets les bonnes valeurs suivant ce que l'on a besoin:
Dans mon cas, je décide de ne garder que 100 workflows:
$keep = 100
On conservera donc, les 100 exécutions les plus récentes.
On relance le script pour faire le nettoyage complet
.\cleanup-github-runs.ps1

Depuis le terminal (local)
#output
PS C:\Temp> .\cleanup-github-runs.ps1
Total runs found: 830
Deleting 730 old runs...

Deleting run 29438868418 - Prod Build, Analyze and Deploy Flashcards App
Deleting run 29438855857 - CI - Staging
Deleting run 29438855802 - Auto PR - Staging to Main

//...

Deleting run 20197853503 - Prod Build, Analyze and Deploy Flashcards App
Deleting run 18842325756 - Build and Test Flashcards App
Done!
S'il n'à rien à supprimer, il affichera:
PS C:\Temp> ./cleanup-github-runs.ps1
Total runs found: 100
Deleting 0 old runs...
Done!
Vérification sur la plateforme
Depuis les Actions result: still 100 workflows
Recharger la page plusieurs fois si besoin:
"CTRL+F5"   ou   "CTRL+R"

Améliorations possibles
1. Ne plus mettre le token en dur dans le script
Au lieu de:
$token = "ghp_..."
Utiliser une variable d'environnement: $token = $env:GITHUB_TOKEN
2. Avant d'exécuter le script
$env:GITHUB_TOKEN="YOUR_TOKEN"
.\cleanup-github-runs.ps1
Ainsi, le token ne sera plus enregistré dans le fichier
Une idée de maintenance
Pour aller plus loin, un petit challenge à faire
Comme je gère plusieurs plateformes et outils pour mon projet Flashcards:
GitHub,
GitLab, ..
C'est une pratique que beaucoup d'équipes pourraient adopter, pour éviter que les dépôts s'encombrent avec le temps.
Je pourrait, avec le temps transformer ce script en un outil de maintenance qui ferait plusieurs opérations d'un coup,
par exemple:
Nettoyer des anciens artefacts et runs GitLab.
Cibler les branches, Renovate, Dependabot, ..
Afficher un résumé (nombre de runs supprimés, artefacts, etc.).

Comparatif : Script PowerShell vs GitHub Actions
Critère Script PowerShell (via API) GitHub Actions (Marketplace)
Sécurité du Token Élevée: Le token reste sur la machine local Moyenne: Nécessite d'enregistrer un PAT dans les Secrets du dépôt ou de l'organisation
Automatisation Manuelle: Nécessite de lancer le script depuis votre PC ou de configurer un planificateur de tâches Windows 100% Automatique: S'exécute seul toutes les semaines/mois via un déclencheur schedule (cron)
Coût d'exécution Gratuit: Consomme les ressources de la machine locale Variable: Gratuit pour les dépôts publics; consomme des minutes gratuites GitHub Actions pour les dépôts privés
Périmètre ciblé Workflow Runs: Supprime l'historique complet de l'exécution, ce qui supprime aussi l'artefact lié Artefacts uniquement: Certaines actions ne suppriment que les fichiers lourds sans effacer l'historique du run
Naviguez entre les articlesBrowse through the articles

Laissez-moi un commentaire

En postant un commentaire anonyme, vous adhérez automatiquement aux conditions d'utilisation du site.