Delete artifacts by name to free up storage space and manage workflow artifacts programmatically.
Permanently removes an artifact from GitHub Actions storage.
/**
* Deletes an artifact by name from the current or specified workflow run.
* This operation is irreversible and will permanently remove the artifact and its contents.
* @param artifactName - Name of the artifact to delete
* @param options - Optional cross-repository access configuration
* @returns Promise resolving to deletion confirmation with artifact ID
*/
deleteArtifact(
artifactName: string,
options?: FindOptions
): Promise<DeleteArtifactResponse>;
interface DeleteArtifactResponse {
/** ID of the artifact that was successfully deleted */
id: number;
}
interface FindOptions {
/** Configuration for deleting artifacts from other repositories/runs */
findBy?: {
/** GitHub token with actions:write permissions on target repository */
token: string;
/** ID of the workflow run containing the artifact */
workflowRunId: number;
/** Repository owner (e.g., 'actions') */
repositoryOwner: string;
/** Repository name (e.g., 'toolkit') */
repositoryName: string;
};
}Usage Examples:
import { DefaultArtifactClient } from "@actions/artifact";
const artifact = new DefaultArtifactClient();
// Delete artifact from current workflow run
const result = await artifact.deleteArtifact("temporary-build");
console.log(`Deleted artifact with ID: ${result.id}`);
// Delete multiple artifacts
const artifactsToDelete = ["cache-files", "temp-logs", "debug-info"];
for (const name of artifactsToDelete) {
try {
const result = await artifact.deleteArtifact(name);
console.log(`Deleted ${name} (ID: ${result.id})`);
} catch (error) {
console.warn(`Failed to delete ${name}:`, error.message);
}
}
// Delete artifact from another repository (requires actions:write token)
const externalResult = await artifact.deleteArtifact("old-build", {
findBy: {
token: process.env.GITHUB_TOKEN!, // Must have actions:write permission
workflowRunId: 987654321,
repositoryOwner: "myorg",
repositoryName: "myproject"
}
});
console.log(`Deleted external artifact ID: ${externalResult.id}`);Delete artifacts from other repositories or workflow runs by providing enhanced permissions:
// Setup for cross-repository deletion
const findBy = {
token: process.env.ADMIN_TOKEN!, // Token with actions:write scope
workflowRunId: 123456789, // Target workflow run ID
repositoryOwner: "organization", // Repository owner
repositoryName: "project" // Repository name
};
// Delete from external repository
try {
const result = await artifact.deleteArtifact("build-cache", { findBy });
console.log(`Successfully deleted external artifact ${result.id}`);
} catch (error) {
console.error("Failed to delete external artifact:", error.message);
}Requirements for cross-repository deletion:
actions:write permissions on target repositoryCommon patterns for managing multiple artifacts:
// Delete all artifacts matching a pattern
const artifacts = await artifact.listArtifacts();
const testArtifacts = artifacts.artifacts.filter(art =>
art.name.startsWith("test-")
);
const deletionPromises = testArtifacts.map(art =>
artifact.deleteArtifact(art.name)
.then(result => ({ success: true, id: result.id, name: art.name }))
.catch(error => ({ success: false, error: error.message, name: art.name }))
);
const results = await Promise.all(deletionPromises);
results.forEach(result => {
if (result.success) {
console.log(`✓ Deleted ${result.name} (ID: ${result.id})`);
} else {
console.error(`✗ Failed to delete ${result.name}: ${result.error}`);
}
});
// Delete artifacts older than specific date
const cutoffDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000); // 7 days ago
const oldArtifacts = artifacts.artifacts.filter(art =>
art.createdAt && art.createdAt < cutoffDate
);
for (const oldArtifact of oldArtifacts) {
await artifact.deleteArtifact(oldArtifact.name);
console.log(`Deleted old artifact: ${oldArtifact.name}`);
}Use deletion for effective storage management:
// Monitor storage usage and clean up
async function manageArtifactStorage(maxTotalSize: number) {
const artifacts = await artifact.listArtifacts();
const totalSize = artifacts.artifacts.reduce((sum, art) => sum + art.size, 0);
if (totalSize > maxTotalSize) {
// Sort by creation date (oldest first)
const sortedArtifacts = artifacts.artifacts
.filter(art => art.createdAt)
.sort((a, b) => a.createdAt!.getTime() - b.createdAt!.getTime());
let currentSize = totalSize;
for (const art of sortedArtifacts) {
if (currentSize <= maxTotalSize) break;
await artifact.deleteArtifact(art.name);
currentSize -= art.size;
console.log(`Deleted ${art.name} to free ${art.size} bytes`);
}
}
}
// Clean up temporary artifacts after successful deployment
async function cleanupAfterDeploy() {
const tempPatterns = ["temp-", "cache-", "debug-"];
const artifacts = await artifact.listArtifacts();
for (const art of artifacts.artifacts) {
if (tempPatterns.some(pattern => art.name.startsWith(pattern))) {
await artifact.deleteArtifact(art.name);
console.log(`Cleaned up temporary artifact: ${art.name}`);
}
}
}Handle common deletion errors:
import {
ArtifactNotFoundError,
NetworkError,
GHESNotSupportedError
} from "@actions/artifact";
async function safeDelete(artifactName: string) {
try {
const result = await artifact.deleteArtifact(artifactName);
return { success: true, id: result.id };
} catch (error) {
if (error instanceof ArtifactNotFoundError) {
console.warn(`Artifact '${artifactName}' not found (may already be deleted)`);
return { success: true, alreadyDeleted: true };
} else if (error instanceof NetworkError) {
console.error(`Network error deleting '${artifactName}':`, error.code);
return { success: false, retryable: true, error };
} else if (error instanceof GHESNotSupportedError) {
console.error("Deletion not supported on GitHub Enterprise Server");
return { success: false, retryable: false, error };
} else {
console.error(`Unexpected error deleting '${artifactName}':`, error);
return { success: false, retryable: false, error };
}
}
}
// Usage with retry logic
async function deleteWithRetry(artifactName: string, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const result = await safeDelete(artifactName);
if (result.success || !result.retryable) {
return result;
}
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
console.log(`Retrying deletion of '${artifactName}' in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}actions:write permissions