diff --git a/.changeset/chatty-cougars-collect.md b/.changeset/chatty-cougars-collect.md new file mode 100644 index 00000000000..a49ba48448f --- /dev/null +++ b/.changeset/chatty-cougars-collect.md @@ -0,0 +1,2 @@ +--- +--- \ No newline at end of file diff --git a/.github/workflows/release-unpublish.yaml b/.github/workflows/release-unpublish.yaml new file mode 100644 index 00000000000..6d1ed0ca2cc --- /dev/null +++ b/.github/workflows/release-unpublish.yaml @@ -0,0 +1,28 @@ +name: "Unpublish old versions" + +on: + workflow_dispatch: + inputs: + delete_packages: + type: boolean + description: Delete packages? otherwise dry-run mode will be used + default: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + clean-npm-versions: + name: Unpublish versions next, preview, master... + runs-on: buildjet-4vcpu-ubuntu-2204 + steps: + - uses: actions/checkout@v3 + - uses: FuelLabs/github-actions/setups/node@master + - uses: FuelLabs/github-actions/setups/npm@master + with: + npm-token: ${{ secrets.NPM_TOKEN }} + - run: | + node ./scripts/release-unpublish.js + env: + DELETE_PACKAGES: ${{ github.event.inputs.delete_packages}} diff --git a/package.json b/package.json index e8c4adb9214..8befa5f1582 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "packageManager": "pnpm@8.9.0", "scripts": { + "dan": "tsx ./scripts/release-unpublish.ts", "dev": "nodemon --config nodemon.config.json -x 'pnpm build:packages'", "build": "turbo run build", "build:packages": "turbo run build --filter=!docs", @@ -49,6 +50,7 @@ "@changesets/get-github-info": "^0.5.2", "@fuel-ts/forc": "workspace:*", "@fuel-ts/fuel-core": "workspace:*", + "@fuel-ts/versions": "workspace:^", "@internal/tsup": "workspace:*", "@jest/types": "^29.5.0", "@types/jest": "^29.5.0", @@ -57,6 +59,7 @@ "@types/web": "^0.0.65", "@typescript-eslint/eslint-plugin": "^6.9.0", "@typescript-eslint/parser": "^6.9.0", + "compare-versions": "^6.1.0", "conventional-changelog-angular": "^5.0.13", "dotenv": "^9.0.2", "eslint": "^8.52.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 972198c807d..654e67171df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@fuel-ts/fuel-core': specifier: workspace:* version: link:packages/fuel-core + '@fuel-ts/versions': + specifier: workspace:^ + version: link:packages/versions '@internal/tsup': specifier: workspace:* version: link:internal/tsup @@ -47,6 +50,9 @@ importers: '@typescript-eslint/parser': specifier: ^6.9.0 version: 6.9.1(eslint@8.52.0)(typescript@5.2.2) + compare-versions: + specifier: ^6.1.0 + version: 6.1.0 conventional-changelog-angular: specifier: ^5.0.13 version: 5.0.13 @@ -8466,6 +8472,10 @@ packages: dot-prop: 5.3.0 dev: true + /compare-versions@6.1.0: + resolution: {integrity: sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==} + dev: true + /compressible@2.0.18: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} diff --git a/scripts/release-unpublish.ts b/scripts/release-unpublish.ts new file mode 100644 index 00000000000..3317646127e --- /dev/null +++ b/scripts/release-unpublish.ts @@ -0,0 +1,57 @@ +import { versions } from '@fuel-ts/versions'; +import { exec } from 'child_process'; +import { compare } from 'compare-versions'; +import { readFileSync, readdirSync } from 'fs'; +import { join } from 'path'; + +const DELETE_TAGS = /next|pr/; +const { FUELS: CURRENT_VERSION } = versions; +const DELETE_PACKAGES = process.env.DELETE_PACKAGES === 'true'; +const dryRun = DELETE_PACKAGES ? '' : '--dry-run'; + +const { log, error } = console; + +const getPublicPackages = () => { + const packagesDir = join(__dirname, '../packages'); + const packages = readdirSync(packagesDir, { withFileTypes: true }); + const packagesNames = packages.map((p) => { + try { + const packageContent = readFileSync(join(packagesDir, p.name, 'package.json'), 'utf8'); + const packageJson = JSON.parse(packageContent.toString()); + return packageJson.private ? null : packageJson.name; + } catch (err) { + return null; + } + }); + return packagesNames.filter((p) => !!p); +}; + +const main = async () => { + const packages = getPublicPackages(); + await packages.map(async (packageName) => { + log(`📦 Fetching ${packageName} versions`); + const { versions: packageVersions } = await fetch( + `https://registry.npmjs.org/${packageName}` + ).then((resp) => resp.json()); + + const versionsToDelete = Object.keys(packageVersions).filter( + (packageVersion) => + packageVersion.search(DELETE_TAGS) > -1 && !compare(packageVersion, CURRENT_VERSION, '>=') + ); + log('The following versions will be deleted:'); + log(versionsToDelete.map((v) => ` - ${v}`).join('\n')); + versionsToDelete.map(async (versionToDelete) => { + const { stderr } = await exec(`npm unpublish ${packageName}@${versionToDelete} ${dryRun}`); + if (stderr) { + log(`❌ Error ${packageName}@${versionToDelete} not deleted!\n`); + } else { + log(`✅ Package ${packageName}@${versionToDelete} deleted!\n`); + } + }); + }); +}; + +main().catch((err) => { + error(err); + process.exit(1); +});