Skip to content

Instantly share code, notes, and snippets.

@DPatrickBoyd
Created April 20, 2023 22:51
Show Gist options
  • Save DPatrickBoyd/afb54165df0f51903be3f0edea77f9cb to your computer and use it in GitHub Desktop.
Save DPatrickBoyd/afb54165df0f51903be3f0edea77f9cb to your computer and use it in GitHub Desktop.
#!/bin/bash
# Change the date under CUTOFF_DATE to change how far back you want to delete
# Install the GitHub CLI tool by following the instructions in the official documentation: https://cli.github.com/manual/installation
# Make sure you auth first to github with 'gh auth login'
REPO_OWNER="OWNER"
REPO_NAME="REPO_NAME"
CUTOFF_DATE=$(date --date='30 days ago' +'%Y-%m-%dT%H:%M:%SZ')
PAGE=1
while true; do
# Retrieve a page of artifacts
ART_EXIST=$(gh api repos/$REPO_OWNER/$REPO_NAME/actions/artifacts?per_page=100\&page=$PAGE | jq -r '.artifacts[]')
ARTIFACTS=$(gh api repos/$REPO_OWNER/$REPO_NAME/actions/artifacts?per_page=100\&page=$PAGE | jq -r '.artifacts[] | select(.created_at < "'"$CUTOFF_DATE"'") | .id')
echo $PAGE
# If there are no more artifacts, exit the loop
if [[ -z "$ART_EXIST" ]]; then
break
fi
# Loop through the artifacts on this page and delete the old ones
for ARTIFACT_ID in $ARTIFACTS; do
ARTIFACT_NAME=$(gh api repos/$REPO_OWNER/$REPO_NAME/actions/artifacts/$ARTIFACT_ID | jq -r '.name')
echo "Deleting artifact $ARTIFACT_NAME (ID: $ARTIFACT_ID)..."
gh api repos/$REPO_OWNER/$REPO_NAME/actions/artifacts/$ARTIFACT_ID -X DELETE
done
# Increment the page counter
PAGE=$((PAGE+1))
done
@deliciouslytyped
Copy link

Thanks for this.

@michalcs
Copy link

michalcs commented Jun 8, 2023

This has worked beautifully! Thanks a lot 🙌

On macOS I had to adjust the date slightly

CUTOFF_DATE=$(date -u -v-30d +'%Y-%m-%dT%H:%M:%SZ')

@k4mrul
Copy link

k4mrul commented Aug 7, 2023

Thanks

@keifgwinn
Copy link

get_date() {
    CUTOFF_DATE=$(date --date='30 days ago' +'%Y-%m-%dT%H:%M:%SZ' 2>/dev/null)
    if [ $? -ne 0 ]; then
        CUTOFF_DATE=$(date -v-30d +'%Y-%m-%dT%H:%M:%SZ' 2>/dev/null)
    fi
    echo $CUTOFF_DATE
}

CUTOFF_DATE=$(get_date)

handling the date on mac

@zirkelc
Copy link

zirkelc commented Mar 20, 2024

Works great!

@illusion0001
Copy link

Powershell version. I couldn't get cutoff date to work so it will delete all artifacts one by one

$REPO_OWNER = "OWNER"
$REPO_NAME = "REPO_NAME"
$CUTOFF_DATE = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddTHH:mm:ssZ")
$PAGE = 1

while ($true) {
    # Retrieve a page of artifacts
    $ART_EXIST = gh api "repos/$REPO_OWNER/$REPO_NAME/actions/artifacts?per_page=100&page=$PAGE" | ConvertFrom-Json
    $ARTIFACTS = $ART_EXIST.artifacts
    #Write-Output $ART_EXIST.artifacts
    Write-Output $PAGE
    #Write-Output $ARTIFACTS

    # If there are no more artifacts, exit the loop
    if ($ART_EXIST.total_count -eq 0) {
        break
    }

    # Loop through the artifacts on this page and delete the old ones
    foreach ($ARTIFACT in $ARTIFACTS) {
        $ARTIFACT_NAME = $ARTIFACT.name
        $ARTIFACT_ID = $ARTIFACT.id
        Write-Output "Deleting artifact $ARTIFACT_NAME (ID: $ARTIFACT_ID)..."
        gh api "repos/$REPO_OWNER/$REPO_NAME/actions/artifacts/$ARTIFACT_ID" -X Delete
    }

    # Increment the page counter
    $PAGE++
}

@CodingScott
Copy link

@illusion0001 Thanks for this!

@RealDyllon
Copy link

Thanks for sharing this! You might want to add --silent at the end of the delete call so that the script doesn't get interrupted by the response body.

@dijitali
Copy link

Tweaked the PowerShell option above to support the pagination, different retention for the main branch and include some size estimates in the output:

$repoOwner = "OWNER"
$repoName = "REPO_NAME"
$mainRetentionDate = (Get-Date).AddDays(-30)
$branchRetentionDate = (Get-Date).AddDays(-7)
$pageSize = 100
$page = 1

# Retrieve first page of artifacts
$response = gh api "repos/$repoOwner/$repoName/actions/artifacts?per_page=$pageSize&page=$page" | ConvertFrom-Json
$total_pages = [math]::Ceiling(($response.total_count / $pageSize))

$artifacts = $response.artifacts

# Paginate remainder
for ($page = 2; $page -le $total_pages; $page++) {
  $response = gh api "repos/$repoOwner/$repoName/actions/artifacts?per_page=$pageSize&page=$page" | ConvertFrom-Json
  $artifacts += $response.artifacts
}

Write-Host ('Total artifact count: ' + $artifacts.Length)
Write-Host ('Total artifact size (bytes): ' + ($artifacts | Measure-Object -Property size_in_bytes -Sum).Sum)

$spaceSaved = 0
foreach ($artifact in $artifacts) {
  switch ($artifact.workflow_run_head_branch) {
    'main' { 
      if ( (Get-Date $artifact.created_at) -lt $mainRetentionDate) {
        Write-Host ('Removing artifact with id: ' + $artifact.id + `
            ' name: ' + $artifact.name + `
            ' created at ' + $artifact.created_at + `
            ' for branch ' + $artifact.workflow_run.head_branch)
        
        #Remove
        gh api "repos/$repoOwner/$repoName/actions/artifacts/$($artifact.id)" -X Delete --silent | Out-Null
        
        $spaceSaved += $artifact.size_in_bytes
      }
    }
    Default {
      if ( (Get-Date $artifact.created_at) -lt $branchRetentionDate) {
        Write-Host ('Removing artifact with id: ' + $artifact.id + `
            ' name: ' + $artifact.name + `
            ' created at ' + $artifact.created_at + `
            ' for branch ' + $artifact.workflow_run.head_branch)
        
        #Remove
        gh api "repos/$repoOwner/$repoName/actions/artifacts/$($artifact.id)" -X Delete | Out-Null

        $spaceSaved += $artifact.size_in_bytes
      }
    }
  }
}

Write-Host 'Total space saved (bytes): ' $spaceSaved

e.g.:

Total artifact count: 279
Total artifact size (bytes): 1331854445
...
Removing artifact with id: 1859067075 name: playwright-report created at 08/27/2024 10:50:44 for branch main
Removing artifact with id: 1859064083 name: hugo-public created at 08/27/2024 10:49:57 for branch main
Removing artifact with id: 1846106084 name: playwright-report created at 08/23/2024 08:18:41 for branch main
Removing artifact with id: 1846079142 name: playwright-report created at 08/23/2024 08:11:01 for branch main
Removing artifact with id: 1833212961 name: playwright-report created at 08/20/2024 15:50:48 for branch main
Total space saved (bytes):  1207672413

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment