Skip to content

Commit a1a65cb

Browse files
authored
Add Stack Deploy Options (#22)
* Add Stack Deploy Options * Add checks on resolve_image option * Update output * Update output * Update README.md * Update README.md and output * Fix * Use default if resolve_image is invalid * Remove command duplication * Update README.md * Update README.md * Update summary.sh * Update README.md * Update test.yaml * Update README.md * Update README.md * Update README.md
1 parent 62b296b commit a1a65cb

File tree

6 files changed

+202
-55
lines changed

6 files changed

+202
-55
lines changed

.github/workflows/lint.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
# cat "${GITHUB_EVENT_PATH}"
2222

2323
- name: "ShellCheck"
24-
if: ${{ always() }}
24+
if: ${{ !cancelled() }}
2525
uses: ludeeus/action-shellcheck@master
2626
env:
2727
SHELLCHECK_OPTS: -x

.github/workflows/test.yaml

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ on:
66
- cron: "18 18 * * 1,3,5"
77
push:
88
branches: ["**"]
9-
paths:
10-
- "dist/**"
11-
- "src/**"
12-
- ".github/workflows/test.yaml"
13-
- "Dockerfile"
14-
- "package*.json"
15-
- "requirements.txt"
16-
- "action.yaml"
9+
#paths:
10+
# - "dist/**"
11+
# - "src/**"
12+
# - ".github/workflows/test.yaml"
13+
# - "Dockerfile"
14+
# - "package*.json"
15+
# - "requirements.txt"
16+
# - "action.yaml"
1717

1818
env:
1919
PRIVATE_IMAGE: ${{ vars.PRIVATE_IMAGE || 'smashedr/alpine-private:latest' }}
@@ -25,7 +25,7 @@ jobs:
2525
runs-on: ubuntu-latest
2626
timeout-minutes: 5
2727
concurrency:
28-
group: test
28+
group: ${{ github.workflow }}
2929
cancel-in-progress: true
3030

3131
steps:
@@ -37,14 +37,15 @@ jobs:
3737
# cat "${GITHUB_EVENT_PATH}"
3838

3939
- name: "1: Write YAML"
40-
if: ${{ always() }}
40+
if: ${{ !cancelled() }}
4141
uses: teunmooij/yaml@v1
4242
with:
43-
data: '{"version":"3.8","services":{"alpine":{"image":"alpine:latest","command":"tail -f /dev/null"}}}'
4443
to-file: "docker-compose.yaml"
44+
data: |
45+
{"version":"3.8","services":{"alpine":{"image":"alpine:latest","command":"tail -f /dev/null"}}}
4546
4647
- name: "1: Test Password"
47-
if: ${{ always() }}
48+
if: ${{ !cancelled() }}
4849
uses: ./
4950
with:
5051
name: test_stack-deploy
@@ -53,17 +54,20 @@ jobs:
5354
port: ${{ secrets.DOCKER_PORT }}
5455
user: ${{ secrets.DOCKER_USER }}
5556
pass: ${{ secrets.DOCKER_PASS }}
56-
#ssh_key: "${{ secrets.DOCKER_SSH_KEY }}"
57+
#ssh_key: ${{ secrets.DOCKER_SSH_KEY }}
58+
detach: false
59+
resolve_image: "changed"
5760

5861
- name: "2: Write YAML"
59-
if: ${{ always() && !github.event.act }}
62+
if: ${{ !cancelled() && !github.event.act }}
6063
uses: teunmooij/yaml@v1
6164
with:
62-
data: '{"version":"3.8","services":{"alpine":{"image":"${{ env.PRIVATE_IMAGE }}","command":"tail -f /dev/null"}}}'
6365
to-file: "docker-compose.yaml"
66+
data: |
67+
{"version":"3.8","services":{"alpine":{"image":"${{ env.PRIVATE_IMAGE }}","command":"tail -f /dev/null"}}}
6468
6569
- name: "2: Test SSH and Auth"
66-
if: ${{ always() && !github.event.act }}
70+
if: ${{ !cancelled() && !github.event.act }}
6771
uses: ./
6872
with:
6973
name: test_stack-deploy
@@ -72,7 +76,8 @@ jobs:
7276
port: ${{ secrets.DOCKER_PORT }}
7377
user: ${{ secrets.DOCKER_USER }}
7478
#pass: ${{ secrets.DOCKER_PASS }}
75-
ssh_key: "${{ secrets.DOCKER_SSH_KEY }}"
79+
ssh_key: ${{ secrets.DOCKER_SSH_KEY }}
80+
prune: true
7681
registry_user: ${{ vars.DOCKER_HUB_USER }}
7782
registry_pass: ${{ secrets.DOCKER_HUB_PASS }}
7883
summary: false

README.md

Lines changed: 136 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
[![GitHub Last Commit](https://img.shields.io/github/last-commit/cssnr/stack-deploy-action?logo=github&logoColor=white&label=updated)](https://github.com/cssnr/stack-deploy-action/graphs/commit-activity)
66
[![Codeberg Last Commit](https://img.shields.io/gitea/last-commit/cssnr/stack-deploy-action/master?gitea_url=https%3A%2F%2Fcodeberg.org%2F&logo=codeberg&logoColor=white&label=updated)](https://codeberg.org/cssnr/stack-deploy-action)
77
[![GitHub Top Language](https://img.shields.io/github/languages/top/cssnr/stack-deploy-action?logo=htmx&logoColor=white)](https://github.com/cssnr/stack-deploy-action)
8+
[![GitHub Discussions](https://img.shields.io/github/discussions/cssnr/stack-deploy-action)](https://github.com/cssnr/stack-deploy-action/discussions)
89
[![GitHub Forks](https://img.shields.io/github/forks/cssnr/stack-deploy-action?style=flat&logo=github)](https://github.com/cssnr/stack-deploy-action/forks)
910
[![GitHub Repo Stars](https://img.shields.io/github/stars/cssnr/stack-deploy-action?style=flat&logo=github&logoColor=white)](https://github.com/cssnr/stack-deploy-action/stargazers)
1011
[![GitHub Org Stars](https://img.shields.io/github/stars/cssnr?style=flat&logo=github&logoColor=white&label=org%20stars)](https://cssnr.github.io/)
@@ -20,6 +21,8 @@
2021
This action deploys a docker stack from a compose file to a remote docker host using SSH Password or Key File Authentication.
2122
You can also optionally authenticate against a private registry using a username and password.
2223

24+
This action uses a remote docker context to deploy the stack from the working directory allowing you to easily prepare the workspace for deployment.
25+
2326
For more details see [action.yaml](action.yaml) and [src/main.sh](src/main.sh).
2427

2528
**Portainer Users:** You can deploy directly to Portainer with: [cssnr/portainer-stack-deploy-action](https://github.com/cssnr/portainer-stack-deploy-action)
@@ -30,24 +33,38 @@ For more details see [action.yaml](action.yaml) and [src/main.sh](src/main.sh).
3033
3134
## Inputs
3235

33-
| input | required | default | description |
34-
| ------------- | :----------: | --------------------- | --------------------------------- |
35-
| host | **Yes** | - | Remote Docker hostname |
36-
| port | - | `22` | Remote Docker port |
37-
| user | **Yes** | - | Remote Docker username |
38-
| pass | or `ssh_key` | - | Remote Docker password \* |
39-
| ssh_key | or `pass` | - | Remote SSH Key file \* |
40-
| name | **Yes** | - | Docker Stack name |
41-
| file | - | `docker-compose.yaml` | Docker Compose file |
42-
| env_file | - | - | Docker Environment file |
43-
| registry_auth | - | - | Enable Registry Authentication \* |
44-
| registry_host | - | - | Registry Authentication Host \* |
45-
| registry_user | - | - | Registry Authentication User \* |
46-
| registry_pass | - | - | Registry Authentication Pass \* |
47-
| summary | - | `true` | Add Job Summary \* |
36+
| input | required | default | description |
37+
| ------------- | :----------: | --------------------- | ----------------------------------------- |
38+
| name | **Yes** | - | Docker Stack Name |
39+
| file | - | `docker-compose.yaml` | Docker Compose File |
40+
| host | **Yes** | - | Remote Docker Hostname |
41+
| port | - | `22` | Remote Docker Port |
42+
| user | **Yes** | - | Remote Docker Username |
43+
| pass | or `ssh_key` | - | Remote Docker Password \* |
44+
| ssh_key | or `pass` | - | Remote SSH Key File \* |
45+
| env_file | - | - | Docker Environment File \* |
46+
| detach | - | `true` | Detach Flag, `false` to disable \* |
47+
| prune | - | `false` | Prune Flag, `true` to enable |
48+
| resolve_image | - | `always` | Options [`always`, `changed`, `never`] \* |
49+
| registry_auth | - | - | Enable Registry Authentication \* |
50+
| registry_host | - | - | Registry Authentication Host \* |
51+
| registry_user | - | - | Registry Authentication Username \* |
52+
| registry_pass | - | - | Registry Authentication Password \* |
53+
| summary | - | `true` | Add Job Summary \* |
54+
55+
For additional details on inputs, see the stack deploy [documentation](https://docs.docker.com/reference/cli/docker/stack/deploy/).
4856

4957
**pass/ssh_key** - You must provide either a `pass` or `ssh_key`.
5058

59+
**env_file** - Variables in this file are exported before running stack deploy.
60+
To use a docker `env_file` specify it in your compose file and make it available in a previous step.
61+
If you need compose file templating this can also be done in a previous step.
62+
63+
**detach** - Set this to `false` to not exit immediately and wait for the services to converge.
64+
This will generate extra output in the logs and is useful for debugging deployments.
65+
66+
**resolve_image** - When the default `always` is used, this argument is omitted.
67+
5168
**registry_auth** - Set to `true` to deploy with `--with-registry-auth`.
5269

5370
**registry_host** - To run `docker login` on another registry. Example: `ghcr.io`
@@ -56,16 +73,32 @@ For more details see [action.yaml](action.yaml) and [src/main.sh](src/main.sh).
5673

5774
**summary** - Write a Summary for the job. To disable this set to `false`.
5875

76+
To view a workflow run, click on a recent
77+
[Test](https://github.com/cssnr/stack-deploy-action/actions/workflows/test.yaml) job _(requires login)_.
78+
5979
<details><summary>👀 View Example Job Summary</summary>
6080

6181
---
6282

63-
🎉 Stack `test-stack` Successfully Deployed.
83+
🎉 Stack `test_stack-deploy` Successfully Deployed.
84+
85+
```text
86+
docker stack deploy --detach=false --resolve-image=changed -c docker-compose.yaml test_stack-deploy
87+
```
6488

6589
<details><summary>Results</summary>
6690

6791
```text
68-
Updating service test-stack_alpine (id: ewi9ck5hcdmmvaj8ms0te4t8r)
92+
Updating service test_stack-deploy_alpine (id: tdk8v42m0rvp9hz4rbfrtszb6)
93+
1/1:
94+
overall progress: 0 out of 1 tasks
95+
overall progress: 1 out of 1 tasks
96+
verify: Waiting 5 seconds to verify that tasks are stable...
97+
verify: Waiting 4 seconds to verify that tasks are stable...
98+
verify: Waiting 3 seconds to verify that tasks are stable...
99+
verify: Waiting 2 seconds to verify that tasks are stable...
100+
verify: Waiting 1 seconds to verify that tasks are stable...
101+
verify: Service tdk8v42m0rvp9hz4rbfrtszb6 converged
69102
```
70103

71104
</details>
@@ -74,8 +107,24 @@ Updating service test-stack_alpine (id: ewi9ck5hcdmmvaj8ms0te4t8r)
74107

75108
</details>
76109

77-
To view a workflow run, click on a recent
78-
[Test](https://github.com/cssnr/stack-deploy-action/actions/workflows/test.yaml) job _(requires login)_.
110+
```yaml
111+
- name: 'Stack Deploy'
112+
uses: cssnr/stack-deploy-action@v1
113+
with:
114+
name: 'stack-name'
115+
file: 'docker-compose-swarm.yaml'
116+
host: ${{ secrets.DOCKER_HOST }}
117+
port: ${{ secrets.DOCKER_PORT }}
118+
user: ${{ secrets.DOCKER_USER }}
119+
pass: ${{ secrets.DOCKER_PASS }} # not needed with ssh_key
120+
ssh_key: ${{ secrets.DOCKER_SSH_KEY }} # not needed with pass
121+
```
122+
123+
## Examples
124+
125+
💡 _Click on a heading to expand or collapse an example._
126+
127+
<details open><summary>With password, docker login and --with-registry-auth</summary>
79128
80129
```yaml
81130
- name: 'Stack Deploy'
@@ -87,9 +136,33 @@ To view a workflow run, click on a recent
87136
port: ${{ secrets.DOCKER_PORT }}
88137
user: ${{ secrets.DOCKER_USER }}
89138
pass: ${{ secrets.DOCKER_PASS }}
139+
registry_host: 'ghcr.io'
140+
registry_user: ${{ vars.GHCR_USER }}
141+
registry_pass: ${{ secrets.GHCR_PASS }}
142+
```
143+
144+
</details>
145+
146+
<details><summary>With SSH key, --prune, --detach=false and --resolve-image=changed</summary>
147+
148+
```yaml
149+
- name: 'Stack Deploy'
150+
uses: cssnr/stack-deploy-action@v1
151+
with:
152+
name: 'stack-name'
153+
file: 'docker-compose-swarm.yaml'
154+
host: ${{ secrets.DOCKER_HOST }}
155+
port: ${{ secrets.DOCKER_PORT }}
156+
user: ${{ secrets.DOCKER_USER }}
157+
ssh_key: ${{ secrets.DOCKER_SSH_KEY }}
158+
detach: false
159+
prune: true
160+
resolve_image: 'changed'
90161
```
91162
92-
Use `docker login` and enable `--with-registry-auth`
163+
</details>
164+
165+
<details><summary>With All Inputs</summary>
93166
94167
```yaml
95168
- name: 'Stack Deploy'
@@ -100,15 +173,22 @@ Use `docker login` and enable `--with-registry-auth`
100173
host: ${{ secrets.DOCKER_HOST }}
101174
port: ${{ secrets.DOCKER_PORT }}
102175
user: ${{ secrets.DOCKER_USER }}
103-
pass: ${{ secrets.DOCKER_PASS }}
176+
pass: ${{ secrets.DOCKER_PASS }} # not needed with ssh_key
177+
ssh_key: ${{ secrets.DOCKER_SSH_KEY }} # not needed with pass
178+
env_file: 'stack.env'
179+
detach: true
180+
prune: false
181+
resolve_image: 'always'
182+
registry_auth: true # not needed with registry_pass/registry_user
104183
registry_host: 'ghcr.io'
105184
registry_user: ${{ vars.GHCR_USER }}
106185
registry_pass: ${{ secrets.GHCR_PASS }}
186+
summary: true
107187
```
108188
109-
## Examples
189+
</details>
110190
111-
Simple Example
191+
<details><summary>Simple Workflow Example</summary>
112192
113193
```yaml
114194
name: 'Stack Deploy Action'
@@ -137,7 +217,9 @@ jobs:
137217
pass: ${{ secrets.DOCKER_PASS }}
138218
```
139219
140-
Full Example
220+
</details>
221+
222+
<details><summary>Full Workflow Example</summary>
141223
142224
```yaml
143225
name: 'Stack Deploy Action'
@@ -153,11 +235,15 @@ on:
153235
env:
154236
REGISTRY: 'ghcr.io'
155237

238+
concurrency:
239+
group: ${{ github.workflow }}
240+
cancel-in-progress: true
241+
156242
jobs:
157243
build:
158244
name: 'Build'
159245
runs-on: ubuntu-latest
160-
timeout-minutes: 5
246+
timeout-minutes: 15
161247
permissions:
162248
packages: write
163249

@@ -168,7 +254,7 @@ jobs:
168254
- name: 'Setup Buildx'
169255
uses: docker/setup-buildx-action@v2
170256
with:
171-
platforms: linux/amd64,linux/arm64
257+
platforms: 'linux/amd64,linux/arm64'
172258

173259
- name: 'Docker Login'
174260
uses: docker/login-action@v3
@@ -181,14 +267,14 @@ jobs:
181267
id: tags
182268
uses: smashedr/docker-tags-action@v1
183269
with:
184-
images: '$${{ env.REGISTRY }}/${{ github.repository }}'
270+
images: $${{ env.REGISTRY }}/${{ github.repository }}
185271
tags: ${{ inputs.tags }}
186272

187273
- name: 'Build and Push'
188274
uses: docker/build-push-action@v6
189275
with:
190276
context: .
191-
platforms: linux/amd64,linux/arm64
277+
platforms: 'linux/amd64,linux/arm64'
192278
push: true
193279
tags: ${{ steps.tags.outputs.tags }}
194280
labels: ${{ steps.tags.outputs.labels }}
@@ -211,9 +297,30 @@ jobs:
211297
host: ${{ secrets.DOCKER_HOST }}
212298
port: ${{ secrets.DOCKER_PORT }}
213299
user: ${{ secrets.DOCKER_USER }}
214-
ssh_key: '${{ secrets.DOCKER_SSH_KEY }}'
300+
ssh_key: ${{ secrets.DOCKER_SSH_KEY }}
301+
302+
cleanup:
303+
name: 'Cleanup'
304+
runs-on: ubuntu-latest
305+
timeout-minutes: 5
306+
needs: deploy
307+
permissions:
308+
contents: read
309+
packages: write
310+
311+
steps:
312+
- name: 'Purge Cache'
313+
uses: cssnr/cloudflare-purge-cache-action@v2
314+
with:
315+
token: ${{ secrets.CLOUDFLARE_API_TOKEN }}
316+
zones: cssnr.com
215317
```
216318
319+
</details>
320+
321+
For more examples, you can check out other projects using this action:
322+
https://github.com/cssnr/stack-deploy-action/network/dependents
323+
217324
# Support
218325
219326
For general help or to request a feature see:

action.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ inputs:
3232
env_file:
3333
description: "Environment File"
3434
required: false
35+
detach:
36+
description: "Detach Flag"
37+
required: false
38+
default: "true"
39+
prune:
40+
description: "Prune Flag"
41+
required: false
42+
default: "false"
43+
resolve_image:
44+
description: "Resolve Image Flag"
45+
required: false
46+
default: "always"
3547
registry_auth:
3648
description: "Enable Registry Auth"
3749
required: false

0 commit comments

Comments
 (0)