Created
October 6, 2025 11:35
-
-
Save jcosmo/76e87d46f3fc5169efa3679e45df1c16 to your computer and use it in GitHub Desktop.
Remove old artifacts from azure devops
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const org = "YOUR_ORG"; | |
| const feed = "YOUR_FEED"; | |
| const pat = process.env.AZDO_PAT; // PAT with Packaging (read/write/delete) | |
| const namePattern = /^pkg\.pkg/; // for a particular artifact use /^pkg\.pkg:foo-bar/ | |
| if (!pat) { | |
| console.error("❌ Missing AZDO_PAT environment variable"); | |
| process.exit(1); | |
| } | |
| const auth = Buffer.from(":" + pat).toString("base64"); | |
| async function getPackages() { | |
| const method = "GET" | |
| const url = `https://feeds.dev.azure.com/${org}/_apis/packaging/feeds/${feed}/packages?includeAllVersions=true&api-version=7.1-preview.1`; | |
| const res = await fetch(url, { | |
| method, | |
| headers: { | |
| "Authorization": `Basic ${auth}`, | |
| "Content-Type": "application/json" | |
| } | |
| }); | |
| if (!res.ok) { | |
| const text = await res.text(); | |
| throw new Error(`${method} ${url} failed: ${res.status} ${text}`); | |
| } | |
| return res.json(); | |
| } | |
| async function del(url) { | |
| const method = "DELETE" | |
| const res = await fetch(url, { | |
| method, | |
| headers: { | |
| "Authorization": `Basic ${auth}`, | |
| "Content-Type": "application/json" | |
| }, | |
| }); | |
| if (!res.ok) { | |
| const text = await res.text(); | |
| throw new Error(`${method} ${url} failed: ${res.status} ${text}`); | |
| } | |
| } | |
| async function deletePackageVersion(pkg, version) { | |
| const [group, artifact] = pkg.name.split(":") | |
| const versionNum = version.version | |
| const url = `https://pkgs.dev.azure.com/${org}/_apis/packaging/feeds/${feed}/maven/groups/${group}/artifacts/${artifact}/versions/${versionNum}?api-version=7.1-preview.1`; | |
| try { | |
| await del(url); | |
| console.log(`✅ Deleted ${group}:${artifact}:${versionNum}`); | |
| } catch (err) { | |
| console.error(`❌ Failed: ${group}:${artifact}:${versionNum} — ${err.message}`); | |
| } | |
| } | |
| async function run() { | |
| console.log("Fetching packages..."); | |
| const packages = await getPackages(); | |
| for (const pkg of packages.value) { | |
| if (!namePattern.test(pkg.name)) continue; | |
| console.log(`📦 Checking ${pkg.name} for old versions`); | |
| const packageId = pkg.id; | |
| for (const version of pkg.versions) { | |
| const versionId = version.id; | |
| const published = new Date(version.publishDate); | |
| if (published.getFullYear() <= 2021) { | |
| console.log(` → Deleting ${pkg.name}@${version.version} (published ${published.toISOString()})`); | |
| await deletePackageVersion(pkg, version); | |
| } | |
| } | |
| } | |
| console.log("✅ Done."); | |
| } | |
| run().catch(err => console.error("Fatal error:", err)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment