Update action to update git stacks

This commit is contained in:
Julius Freudenberger 2023-08-17 19:17:58 +02:00
parent b779a44ee2
commit 646000f132
5 changed files with 59 additions and 104 deletions

View file

@ -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"}]'
```

View file

@ -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'

61
dist/index.js vendored
View file

@ -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`, {
headers: {
"X-API-Key": accessToken
}
}, (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({
const postDataObject = {
pullImage: true,
stackFileContent
})
}
const req = client.request(`${portainerUrl}/api/stacks/${stackId}` + (isNaN(endpointId) ? "" : `?endpointId=${endpointId}`), {
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,
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(postData)
}
}, (res) => {
}, (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()
})();

View file

@ -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`, {
headers: {
"X-API-Key": accessToken
}
}, (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({
const postDataObject = {
pullImage: true,
stackFileContent
})
}
const req = client.request(`${portainerUrl}/api/stacks/${stackId}` + (isNaN(endpointId) ? "" : `?endpointId=${endpointId}`), {
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,
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(postData)
}
}, (res) => {
}, (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()

View file

@ -12,8 +12,8 @@
"Portainer"
],
"author": {
"name": "Dzianis Nikifaraŭ",
"email": "dzianis@wirgen.by"
"name": "Julius Freudenberger",
"email": "contact@jfreudenberger.de"
},
"license": "MIT",
"devDependencies": {