mirror of
				https://github.com/JuliusFreudenberger/portainer-stack-git-redeploy-action.git
				synced 2025-11-04 11:33:46 +01:00 
			
		
		
		
	Update action to update git stacks
This commit is contained in:
		
							parent
							
								
									b779a44ee2
								
							
						
					
					
						commit
						646000f132
					
				
					 5 changed files with 59 additions and 104 deletions
				
			
		| 
						 | 
				
			
			@ -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"}]'
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										71
									
								
								dist/index.js
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								dist/index.js
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -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()
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										71
									
								
								index.js
									
										
									
									
									
								
							
							
						
						
									
										71
									
								
								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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,8 +12,8 @@
 | 
			
		|||
    "Portainer"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": {
 | 
			
		||||
    "name": "Dzianis Nikifaraŭ",
 | 
			
		||||
    "email": "dzianis@wirgen.by"
 | 
			
		||||
    "name": "Julius Freudenberger",
 | 
			
		||||
    "email": "contact@jfreudenberger.de"
 | 
			
		||||
  },
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue