or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

deletion.mddiscovery.mddownload.mdindex.mdupload.md
tile.json

deletion.mddocs/

Artifact Deletion

Delete artifacts by name to free up storage space and manage workflow artifacts programmatically.

Capabilities

Delete Artifact

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

Cross-Repository Deletion

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:

  • Token must have actions:write permissions on target repository
  • User must have appropriate repository permissions
  • Workflow run and artifact must exist and be accessible

Bulk Deletion Patterns

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

Storage Management

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

Error Handling

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

Important Considerations

  • Irreversible operation: Deleted artifacts cannot be recovered
  • Permission requirements: Cross-repository deletion requires actions:write permissions
  • Rate limits: Bulk deletions may be subject to API rate limits
  • Storage billing: Deletion immediately frees up storage quota
  • Workflow dependencies: Ensure other jobs/workflows don't depend on artifacts being deleted