diff --git a/README.md b/README.md index 34bbbbf..9402047 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Portainer stack redeploy action This action allows you to update the stack with pull new images if you can't use webhooks. For example, in Portainer Community Edition. +This is a fork of [wirgen/portainer-stack-redeploy-action](https://github.com/wirgen/portainer-stack-redeploy-action) which allows to update stack deployed with a git repository hosting the `docker-compose.yaml`. ## Inputs @@ -20,13 +21,18 @@ This action allows you to update the stack with pull new images if you can't use ID of endpoint (environment). Required if your stack is not in local environment +### `environment` + +Environment variables to set on the stack. When omitted, all existing variables will be cleared from the stack. Must be input as a JSON String; one array of objects each with the keys `name` and `value` + ## Example usage ```yaml -uses: wirgen/portainer-stack-redeploy-action@v1.1 +uses: JuliusFreudenberger/portainer-stack-git-redeploy-action@v1.0 with: portainerUrl: 'https://example.com:9443' accessToken: 'ptr_XXXyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy' stackId: 8 endpointId: 3 + environment: '[{"name":"image_version","value":"xxx"}]' ``` diff --git a/action.yml b/action.yml index c872e12..f21e78f 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,6 @@ -name: Portainer Stack Redeploy -author: Dzianis NikifaraĊ­ -description: Action for request to Portainer API for redeploy stack with pull latest images +name: Portainer Stack Git Redeploy +author: Julius Freudenberger +description: Action for request to Portainer API for redeploy stack configured to use the docker-compose.yaml from a git repository with pull latest images and possibility to set environment variables inputs: portainerUrl: @@ -16,6 +16,9 @@ inputs: description: 'Endpoint ID' required: false default: '' + environment: + description: 'Environment variables' + required: false runs: using: 'node16' diff --git a/dist/index.js b/dist/index.js index 2939d54..a01500e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2823,6 +2823,7 @@ let portainerUrl = core.getInput("portainerUrl") const accessToken = core.getInput("accessToken") const stackId = parseInt(core.getInput("stackId")) const endpointId = parseInt(core.getInput("endpointId")) +const environmentVariables = core.getInput("environment") if (isNaN(stackId)) { core.setFailed("Stack ID must be integer") @@ -2848,67 +2849,39 @@ if (portainerUrl.substring(portainerUrl.length - 1) === "/") { core.setSecret(portainerUrl) core.setSecret(accessToken) -client.get(`${portainerUrl}/api/stacks/${stackId}/file`, { +const postDataObject = { + pullImage: true, +} + +console.dir(environmentVariables) +if (environmentVariables !== undefined && environmentVariables !== "") { + postDataObject.env = JSON.parse(environmentVariables) +} + +const postData = JSON.stringify(postDataObject) + +console.dir(postData) + +const req = client.request(`${portainerUrl}/api/stacks/${stackId}/git/redeploy` + (isNaN(endpointId) ? "" : `?endpointId=${endpointId}`), { + method: "PUT", headers: { - "X-API-Key": accessToken + "X-API-Key": accessToken, + "Content-Type": "application/json", + "Content-Length": Buffer.byteLength(postData) } }, (res) => { if (res.statusCode !== 200) { core.setFailed(res.statusMessage) process.exit(2) } - - let result = "" - res.setEncoding("utf8") - res.on("data", (chunk) => result = result + chunk) - res.on("end", () => { - let stackFileContent - - try { - // noinspection JSUnresolvedVariable - stackFileContent = JSON.parse(result).StackFileContent - - if (stackFileContent === undefined) { - // noinspection ExceptionCaughtLocallyJS - throw Error("Wrong stack file content") - } - } catch (error) { - core.setFailed(error.message) - process.exit(4) - } - - const postData = JSON.stringify({ - pullImage: true, - stackFileContent - }) - - const req = client.request(`${portainerUrl}/api/stacks/${stackId}` + (isNaN(endpointId) ? "" : `?endpointId=${endpointId}`), { - method: "PUT", - headers: { - "X-API-Key": accessToken, - "Content-Type": "application/json", - "Content-Length": Buffer.byteLength(postData) - } - }, (res) => { - if (res.statusCode !== 200) { - core.setFailed(res.statusMessage) - process.exit(2) - } - }) - .on("error", (error) => { - core.setFailed(error.message) - process.exit(3) - }) - - req.write(postData) - req.end() - }) }) .on("error", (error) => { core.setFailed(error.message) process.exit(3) }) - .end() + +req.write(postData) +req.end() })(); diff --git a/index.js b/index.js index 9babea3..84a70a7 100644 --- a/index.js +++ b/index.js @@ -4,6 +4,7 @@ let portainerUrl = core.getInput("portainerUrl") const accessToken = core.getInput("accessToken") const stackId = parseInt(core.getInput("stackId")) const endpointId = parseInt(core.getInput("endpointId")) +const environmentVariables = core.getInput("environment") if (isNaN(stackId)) { core.setFailed("Stack ID must be integer") @@ -29,64 +30,36 @@ if (portainerUrl.substring(portainerUrl.length - 1) === "/") { core.setSecret(portainerUrl) core.setSecret(accessToken) -client.get(`${portainerUrl}/api/stacks/${stackId}/file`, { +const postDataObject = { + pullImage: true, +} + +console.dir(environmentVariables) +if (environmentVariables !== undefined && environmentVariables !== "") { + postDataObject.env = JSON.parse(environmentVariables) +} + +const postData = JSON.stringify(postDataObject) + +console.dir(postData) + +const req = client.request(`${portainerUrl}/api/stacks/${stackId}/git/redeploy` + (isNaN(endpointId) ? "" : `?endpointId=${endpointId}`), { + method: "PUT", headers: { - "X-API-Key": accessToken + "X-API-Key": accessToken, + "Content-Type": "application/json", + "Content-Length": Buffer.byteLength(postData) } }, (res) => { if (res.statusCode !== 200) { core.setFailed(res.statusMessage) process.exit(2) } - - let result = "" - res.setEncoding("utf8") - res.on("data", (chunk) => result = result + chunk) - res.on("end", () => { - let stackFileContent - - try { - // noinspection JSUnresolvedVariable - stackFileContent = JSON.parse(result).StackFileContent - - if (stackFileContent === undefined) { - // noinspection ExceptionCaughtLocallyJS - throw Error("Wrong stack file content") - } - } catch (error) { - core.setFailed(error.message) - process.exit(4) - } - - const postData = JSON.stringify({ - pullImage: true, - stackFileContent - }) - - const req = client.request(`${portainerUrl}/api/stacks/${stackId}` + (isNaN(endpointId) ? "" : `?endpointId=${endpointId}`), { - method: "PUT", - headers: { - "X-API-Key": accessToken, - "Content-Type": "application/json", - "Content-Length": Buffer.byteLength(postData) - } - }, (res) => { - if (res.statusCode !== 200) { - core.setFailed(res.statusMessage) - process.exit(2) - } - }) - .on("error", (error) => { - core.setFailed(error.message) - process.exit(3) - }) - - req.write(postData) - req.end() - }) }) .on("error", (error) => { core.setFailed(error.message) process.exit(3) }) - .end() + +req.write(postData) +req.end() diff --git a/package.json b/package.json index 02d89cc..9694a56 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "Portainer" ], "author": { - "name": "Dzianis NikifaraĊ­", - "email": "dzianis@wirgen.by" + "name": "Julius Freudenberger", + "email": "contact@jfreudenberger.de" }, "license": "MIT", "devDependencies": {