diff --git a/README.md b/README.md index bac5a37..b41e011 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ name: Delete clean Gitpod workspaces weekly on: workflow_dispatch: schedule: - - cron: '0 9 * * MON' # At 9 AM UTC, weekly only on Monday + - cron: "0 9 * * MON" # At 9 AM UTC, weekly only on Monday jobs: delete-clean-workspaces: @@ -26,4 +26,5 @@ jobs: uses: Siddhant-K-code/delete-clean-workspaces@v1.0 with: GITPOD_TOKEN: ${{ secrets.GITPOD_PAT_TOKEN }} + PRINT_SUMMARY: true # Print summary of deleted workspaces. Optional & defaults to false ``` diff --git a/action.yml b/action.yml index b186e8b..5a8aab1 100644 --- a/action.yml +++ b/action.yml @@ -5,6 +5,10 @@ inputs: GITPOD_TOKEN: description: "Gitpod Personal Access token" required: true + PRINT_SUMMARY: + description: "Print summary of deleted workspaces" + required: false + default: "false" outputs: success: description: "true|false based on if the script worked" diff --git a/src/main.js b/src/main.js index fa266fb..04668fc 100644 --- a/src/main.js +++ b/src/main.js @@ -1,28 +1,5 @@ "use strict"; /* eslint-disable @typescript-eslint/no-explicit-any */ -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; -}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -32,12 +9,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } }; Object.defineProperty(exports, "__esModule", { value: true }); -const axios_1 = __importDefault(require("axios")); -const core = __importStar(require("@actions/core")); +var axios_1 = require("axios"); +var core = require("@actions/core"); /** * Lists the workspaces from the Gitpod API and identifies those that should be deleted. * Workspaces are selected for deletion if they are stopped and do not have untracked or uncommitted files. @@ -46,34 +47,42 @@ const core = __importStar(require("@actions/core")); * @returns {Promise} - A promise that resolves to an array of workspace IDs to be deleted. */ function listWorkspaces(gitpodToken) { - return __awaiter(this, void 0, void 0, function* () { - try { - const response = yield axios_1.default.post("https://api.gitpod.io/gitpod.experimental.v1.WorkspacesService/ListWorkspaces", {}, { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${gitpodToken}`, - }, - }); - core.debug("API Response: " + JSON.stringify(response.data)); - const workspaces = response.data.result; - const toDelete = []; - if (!Array.isArray(workspaces)) { - throw new Error("Expected an array of data"); + return __awaiter(this, void 0, void 0, function () { + var response, workspaces, toDelete_1, error_1; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, axios_1.default.post("https://api.gitpod.io/gitpod.experimental.v1.WorkspacesService/ListWorkspaces", {}, { + headers: { + "Content-Type": "application/json", + Authorization: "Bearer ".concat(gitpodToken), + }, + })]; + case 1: + response = _a.sent(); + core.debug("API Response: " + JSON.stringify(response.data)); + workspaces = response.data.result; + toDelete_1 = []; + if (!Array.isArray(workspaces)) { + throw new Error("Expected an array of data"); + } + workspaces.forEach(function (workspace) { + var phaseStopped = workspace.status.instance.status.phase === "PHASE_STOPPED"; + var hasNoUntrackedFiles = !("totalUntrackedFiles" in workspace.status.instance.status.gitStatus); + var hasNoUncommittedFiles = !("totalUncommittedFiles" in workspace.status.instance.status.gitStatus); + if (phaseStopped && hasNoUntrackedFiles && hasNoUncommittedFiles) { + toDelete_1.push(workspace.status.instance.workspaceId); + } + }); + return [2 /*return*/, toDelete_1]; + case 2: + error_1 = _a.sent(); + core.error("Error in listWorkspaces: ".concat(error_1)); + throw error_1; + case 3: return [2 /*return*/]; } - workspaces.forEach((workspace) => { - const phaseStopped = workspace.status.instance.status.phase === "PHASE_STOPPED"; - const hasNoUntrackedFiles = !("totalUntrackedFiles" in workspace.status.instance.status.gitStatus); - const hasNoUncommittedFiles = !("totalUncommittedFiles" in workspace.status.instance.status.gitStatus); - if (phaseStopped && hasNoUntrackedFiles && hasNoUncommittedFiles) { - toDelete.push(workspace.status.instance.workspaceId); - } - }); - return toDelete; - } - catch (error) { - core.error(`Error in listWorkspaces: ${error}`); - throw error; - } + }); }); } /** @@ -83,20 +92,29 @@ function listWorkspaces(gitpodToken) { * @param {string} gitpodToken - The access token for the Gitpod API. */ function deleteWorkspace(workspaceIdOfTargetWorkspace, gitpodToken) { - return __awaiter(this, void 0, void 0, function* () { - try { - yield axios_1.default.post("https://api.gitpod.io/gitpod.experimental.v1.WorkspacesService/DeleteWorkspace", { workspaceId: workspaceIdOfTargetWorkspace }, { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${gitpodToken}`, - }, - }); - core.debug(`Deleted workspace: ${workspaceIdOfTargetWorkspace}`); - } - catch (error) { - core.error(`Error in deleteWorkspace: ${error}`); - throw error; - } + return __awaiter(this, void 0, void 0, function () { + var error_2; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, axios_1.default.post("https://api.gitpod.io/gitpod.experimental.v1.WorkspacesService/DeleteWorkspace", { workspaceId: workspaceIdOfTargetWorkspace }, { + headers: { + "Content-Type": "application/json", + Authorization: "Bearer ".concat(gitpodToken), + }, + })]; + case 1: + _a.sent(); + core.debug("Deleted workspace: ".concat(workspaceIdOfTargetWorkspace)); + return [3 /*break*/, 3]; + case 2: + error_2 = _a.sent(); + core.error("Error in deleteWorkspace: ".concat(error_2)); + throw error_2; + case 3: return [2 /*return*/]; + } + }); }); } /** @@ -104,30 +122,50 @@ function deleteWorkspace(workspaceIdOfTargetWorkspace, gitpodToken) { * lists workspaces, deletes the selected workspaces, and outputs the result. */ function run() { - return __awaiter(this, void 0, void 0, function* () { - try { - const gitpodToken = core.getInput("GITPOD_TOKEN", { required: true }); - const deletedWorkspaces = []; - if (!gitpodToken) { - throw new Error("Gitpod access token is required"); - } - const workspacesToDelete = yield listWorkspaces(gitpodToken); - for (const workspaceId of workspacesToDelete) { - yield deleteWorkspace(workspaceId, gitpodToken); - deletedWorkspaces.push(workspaceId); - } - if (deletedWorkspaces.length > 0) { - core.summary - .addHeading("Workspace IDs of deleted workspaces") - .addList(deletedWorkspaces) - .write(); + return __awaiter(this, void 0, void 0, function () { + var gitpodToken, deletedWorkspaces, workspacesToDelete, _i, workspacesToDelete_1, workspaceId, error_3; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 6, , 7]); + gitpodToken = core.getInput("GITPOD_TOKEN", { required: true }); + deletedWorkspaces = []; + if (!gitpodToken) { + throw new Error("Gitpod access token is required"); + } + return [4 /*yield*/, listWorkspaces(gitpodToken)]; + case 1: + workspacesToDelete = _a.sent(); + _i = 0, workspacesToDelete_1 = workspacesToDelete; + _a.label = 2; + case 2: + if (!(_i < workspacesToDelete_1.length)) return [3 /*break*/, 5]; + workspaceId = workspacesToDelete_1[_i]; + return [4 /*yield*/, deleteWorkspace(workspaceId, gitpodToken)]; + case 3: + _a.sent(); + deletedWorkspaces.push(workspaceId); + _a.label = 4; + case 4: + _i++; + return [3 /*break*/, 2]; + case 5: + if (deletedWorkspaces.length > 0) { + core.summary + .addHeading("Workspace IDs of deleted workspaces") + .addList(deletedWorkspaces) + .write(); + } + core.setOutput("success", "true"); + return [3 /*break*/, 7]; + case 6: + error_3 = _a.sent(); + core.error(error_3.message); + core.setOutput("success", "false"); + return [3 /*break*/, 7]; + case 7: return [2 /*return*/]; } - core.setOutput("success", "true"); - } - catch (error) { - core.error(error.message); - core.setOutput("success", "false"); - } + }); }); } run(); diff --git a/src/main.ts b/src/main.ts index cf59dec..b0d0eb5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -92,6 +92,7 @@ async function deleteWorkspace( async function run() { try { const gitpodToken = core.getInput("GITPOD_TOKEN", { required: true }); + const printSummary = core.getBooleanInput("PRINT_SUMMARY", { required: false }); const deletedWorkspaces: string[] = []; if (!gitpodToken) { @@ -101,10 +102,10 @@ async function run() { const workspacesToDelete = await listWorkspaces(gitpodToken); for (const workspaceId of workspacesToDelete) { await deleteWorkspace(workspaceId, gitpodToken); - deletedWorkspaces.push(workspaceId); + printSummary ? deletedWorkspaces.push(workspaceId) : null; } - if (deletedWorkspaces.length > 0) { + if (deletedWorkspaces.length > 0 && printSummary) { core.summary .addHeading("Workspace IDs of deleted workspaces") .addList(deletedWorkspaces)