diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
new file mode 100644
index 0000000..fce47a0
--- /dev/null
+++ b/.github/workflows/lint.yaml
@@ -0,0 +1,35 @@
+name: "Lint"
+
+on:
+ workflow_dispatch:
+ pull_request:
+ push:
+ branches: [master]
+
+jobs:
+ lint:
+ name: "Lint"
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+
+ steps:
+ - name: "Checkout"
+ uses: actions/checkout@v4
+
+ #- name: "Debug event.json"
+ # run: |
+ # cat "${GITHUB_EVENT_PATH}"
+
+ - name: "ShellCheck"
+ if: ${{ always() }}
+ uses: ludeeus/action-shellcheck@master
+ env:
+ SHELLCHECK_OPTS: -x
+ with:
+ scandir: src
+
+ - name: "Prettier"
+ if: ${{ always() }}
+ run: |
+ npm install prettier
+ npx prettier --check .
diff --git a/.github/workflows/mirror.yaml b/.github/workflows/mirror.yaml
index aa7372a..550f4dc 100644
--- a/.github/workflows/mirror.yaml
+++ b/.github/workflows/mirror.yaml
@@ -2,8 +2,6 @@ name: "Mirror"
on:
workflow_dispatch:
- release:
- types: ["published"]
push:
branches: ["**"]
tags: ["**"]
@@ -21,7 +19,7 @@ jobs:
fetch-depth: 0
- name: "Mirror to Codeberg"
- uses: cssnr/mirror-repository-action@master
+ uses: cssnr/mirror-repository-action@v1
with:
host: https://codeberg.org
create: true
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..9f47abb
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,17 @@
+name: "Release"
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ release:
+ name: "Release"
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ permissions:
+ contents: write
+
+ steps:
+ - name: "Update Tags"
+ uses: cssnr/update-version-tags-action@v1
diff --git a/.github/workflows/tags.yaml b/.github/workflows/tags.yaml
index c235835..9539e5e 100644
--- a/.github/workflows/tags.yaml
+++ b/.github/workflows/tags.yaml
@@ -1,17 +1,23 @@
name: "Tags"
on:
- release:
- types: [published]
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: "Target Tag"
+ required: true
jobs:
tags:
name: "Tags"
runs-on: ubuntu-latest
timeout-minutes: 5
+ permissions:
+ contents: write
steps:
- name: "Update Tags"
uses: cssnr/update-version-tags-action@v1
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ tag: ${{ inputs.tag }}
+ token: ${{ secrets.GH_PAT }}
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index c9114e5..6109824 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -2,9 +2,14 @@ name: "Test"
on:
workflow_dispatch:
- pull_request:
+ schedule:
+ - cron: "23 23 * * 4"
push:
- branches: [master]
+ paths:
+ - "src/**"
+ - ".github/workflows/test.yaml"
+ - "Dockerfile"
+ - "action.yaml"
env:
PRIVATE_IMAGE: "smashedr/alpine-private:latest" # amd64/arm64
@@ -12,20 +17,30 @@ env:
jobs:
test:
name: "Test"
+ if: ${{ !contains(github.event.head_commit.message, '#notest') }}
runs-on: ubuntu-latest
timeout-minutes: 5
+ concurrency:
+ group: test
+ cancel-in-progress: true
steps:
- name: "Checkout"
uses: actions/checkout@v4
- - name: "Write YAML Basic"
+ #- name: "Debug event.json"
+ # run: |
+ # cat "${GITHUB_EVENT_PATH}"
+
+ - name: "1: Write YAML"
+ if: ${{ always() }}
uses: teunmooij/yaml@v1
with:
data: '{"version":"3.8","services":{"alpine":{"image":"alpine:latest","command":"tail -f /dev/null"}}}'
to-file: "docker-compose.yaml"
- - name: "Test Action Basic"
+ - name: "1: Test Password"
+ if: ${{ always() }}
id: test1
uses: ./
with:
@@ -34,16 +49,18 @@ jobs:
host: ${{ secrets.DOCKER_HOST }}
port: ${{ secrets.DOCKER_PORT }}
user: ${{ secrets.DOCKER_USER }}
- #pass: ${{ secrets.DOCKER_PASS }}
- ssh_key: "${{ secrets.DOCKER_SSH_KEY }}"
+ pass: ${{ secrets.DOCKER_PASS }}
+ #ssh_key: "${{ secrets.DOCKER_SSH_KEY }}"
- - name: "Write YAML Private"
+ - name: "2: Write YAML"
+ if: ${{ always() && !github.event.act }}
uses: teunmooij/yaml@v1
with:
data: '{"version":"3.8","services":{"alpine":{"image":"${{ env.PRIVATE_IMAGE }}","command":"tail -f /dev/null"}}}'
to-file: "docker-compose.yaml"
- - name: "Test Action Private"
+ - name: "2: Test SSH and Auth"
+ if: ${{ always() && !github.event.act }}
id: test2
uses: ./
with:
@@ -54,20 +71,6 @@ jobs:
user: ${{ secrets.DOCKER_USER }}
#pass: ${{ secrets.DOCKER_PASS }}
ssh_key: "${{ secrets.DOCKER_SSH_KEY }}"
- #registry_host: "ghcr.io"
registry_user: ${{ vars.DOCKER_HUB_USER }}
registry_pass: ${{ secrets.DOCKER_HUB_PASS }}
-
- lint:
- name: "Lint"
- runs-on: ubuntu-latest
- timeout-minutes: 5
-
- steps:
- - name: "Checkout"
- uses: actions/checkout@v4
-
- - name: "ShellCheck"
- uses: ludeeus/action-shellcheck@master
- with:
- scandir: src
+ summary: false
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..c199942
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,8 @@
+# IDE
+.idea/
+.vscode/
+
+# Tools
+.ruff_cache/
+.mypy_cache/
+.pytest_cache/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..394da11
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,51 @@
+# Contributing
+
+> [!WARNING]
+> This guide is a work in progress and may not be complete.
+
+This is a basic contributing guide and is a work in progress.
+
+## Workflow
+
+1. Fork the repository.
+2. Create a branch in your fork!
+3. Make your changes.
+4. [Test](#Testing) your changes.
+5. Commit and push your changes.
+6. Create a PR to this repository.
+7. Verify the tests pass, otherwise resolve.
+8. Make sure to keep your branch up-to-date.
+
+## Testing
+
+GitHub is easier to set up, but you have to push your commits to test.
+Running locally is harder to set up, but it is much easier to test; and by far recommended!
+
+### GitHub
+
+Add your secrets to GitHub Actions Secrets.
+
+When you push your branch to your repository, the [test.yaml](.github/workflows/test.yaml) should run...
+
+### Locally
+
+To run actions locally you need to install act: https://nektosact.com/installation/index.html
+
+1. Create a `.secrets` file with all your secrets in .env file format.
+2. Run: `act -j test`
+
+To test the private image you must create a `.env` file with, or use --env `PRIVATE_IMAGE=yourimage`
+
+To skip the private image test run with `-e event.json`.
+
+To print your secrets in plan text (insecure) use `--insecure-secrets`
+
+To see all available jobs run `act -l` and see `act --help`
+
+```shell
+act -j test --insecure-secrets -e event.json
+act -j test --insecure-secrets --env PRIVATE_IMAGE=your/private-image:latest
+act -j lint
+```
+
+For more information see the documentation: https://nektosact.com/usage/index.html
diff --git a/Dockerfile b/Dockerfile
index 94261c2..0b84446 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
-FROM docker:24-dind
+FROM docker:28-dind
RUN apk add --update --no-cache bash sshpass
-COPY src/main.sh /main.sh
+COPY src/ /src
-ENTRYPOINT ["bash", "/main.sh"]
+ENTRYPOINT ["bash", "/src/main.sh"]
diff --git a/README.md b/README.md
index c123cf4..a89012f 100644
--- a/README.md
+++ b/README.md
@@ -1,53 +1,82 @@
-[](https://github.com/cssnr/stack-deploy-action/actions/workflows/tags.yaml)
+[](https://github.com/cssnr/stack-deploy-action/actions/workflows/release.yaml)
[](https://github.com/cssnr/stack-deploy-action/actions/workflows/test.yaml)
+[](https://github.com/cssnr/stack-deploy-action/actions/workflows/lint.yaml)
[](https://github.com/cssnr/stack-deploy-action/releases/latest)
[](https://github.com/cssnr/parse-issue-form-action/graphs/commit-activity)
[](https://codeberg.org/cssnr/parse-issue-form-action)
[](https://github.com/cssnr/stack-deploy-action)
-[](https://cssnr.github.io/)
+[](https://github.com/cssnr/stack-deploy-action/forks)
+[](https://github.com/cssnr/stack-deploy-action/stargazers)
+[](https://cssnr.github.io/)
[](https://discord.gg/wXy6m2X8wY)
# Docker Stack Deploy Action
+- [Inputs](#Inputs)
+- [Examples](#Examples)
+- [Support](#Support)
+- [Contributing](#Contributing)
+
This action deploys a docker stack from a compose file to a remote docker host using SSH Password or Key File Authentication.
You can also optionally authenticate against a private registry using a username and password.
For more details see [action.yaml](action.yaml) and [src/main.sh](src/main.sh).
-_Portainer Users_: You can deploy directly to Portainer with: [cssnr/portainer-stack-deploy-action](https://github.com/cssnr/portainer-stack-deploy-action)
+**Portainer Users:** You can deploy directly to Portainer with: [cssnr/portainer-stack-deploy-action](https://github.com/cssnr/portainer-stack-deploy-action)
-- [Inputs](#Inputs)
-- [Examples](#Examples)
-- [Support](#Support)
-- [Contributing](#Contributing)
+> [!NOTE]
+> Please submit a [Feature Request](https://github.com/cssnr/stack-deploy-action/discussions/categories/feature-requests)
+> for new features or [Open an Issue](https://github.com/cssnr/stack-deploy-action/issues)
+> if you find any bugs...
## Inputs
-| input | required | default | description |
-| ------------- | ---------------- | --------------------- | --------------------------------- |
-| host | **Yes** | - | Remote Docker hostname |
-| port | No | `22` | Remote Docker port |
-| user | **Yes** | - | Remote Docker username |
-| pass | Not w/ `ssh_key` | - | Remote Docker password \* |
-| ssh_key | Not w/ `pass` | - | Remote SSH Key file \* |
-| file | No | `docker-compose.yaml` | Docker Compose file |
-| name | **Yes** | - | Docker Stack name |
-| env_file | No | - | Docker Environment file |
-| registry_auth | No | - | Enable Registry Authentication \* |
-| registry_host | No | - | Registry Authentication Host \* |
-| registry_user | No | - | Registry Authentication User \* |
-| registry_pass | No | - | Registry Authentication Pass \* |
+| input | required | default | description |
+| ------------- | :----------: | --------------------- | --------------------------------- |
+| host | **Yes** | - | Remote Docker hostname |
+| port | - | `22` | Remote Docker port |
+| user | **Yes** | - | Remote Docker username |
+| pass | or `ssh_key` | - | Remote Docker password \* |
+| ssh_key | or `pass` | - | Remote SSH Key file \* |
+| name | **Yes** | - | Docker Stack name |
+| file | - | `docker-compose.yaml` | Docker Compose file |
+| env_file | - | - | Docker Environment file |
+| registry_auth | - | - | Enable Registry Authentication \* |
+| registry_host | - | - | Registry Authentication Host \* |
+| registry_user | - | - | Registry Authentication User \* |
+| registry_pass | - | - | Registry Authentication Pass \* |
+| summary | - | `true` | Add Job Summary \* |
+
+**pass/ssh_key** - You must provide either a `pass` or `ssh_key`.
+
+**registry_auth** - Set to `true` to deploy with `--with-registry-auth`.
+
+**registry_host** - To run `docker login` on another registry. Example: `ghcr.io`
-**pass/ssh_key** - You must provide either a `pass` or `ssh_key`
+**registry_user/registry_pass** - Required to run `docker login` before stack deploy.
-**registry_auth** - Set to `true` to deploy with `--with-registry-auth`
+**summary** - Write a Summary for the job. To disable this set to `false`.
-**registry_host** - To run `docker login` on another registry, example: `ghcr.io`
+๐ View Example Job Summary
-**registry_user/registry_pass** - Required to run `docker login` before stack deploy
+---
+
+๐ Stack `test-stack` Successfully Deployed.
+
+Results
+
+```text
+Updating service test-stack_alpine (id: ewi9ck5hcdmmvaj8ms0te4t8r)
+```
+
+
+
+---
+
+
```yaml
-- name: 'Docker Stack Deploy'
+- name: 'Stack Deploy'
uses: cssnr/stack-deploy-action@v1
with:
name: 'stack-name'
@@ -61,7 +90,7 @@ _Portainer Users_: You can deploy directly to Portainer with: [cssnr/portainer-s
Use `docker login` and enable `--with-registry-auth`
```yaml
-- name: 'Docker Stack Deploy'
+- name: 'Stack Deploy'
uses: cssnr/stack-deploy-action@v1
with:
name: 'stack-name'
@@ -80,7 +109,7 @@ Use `docker login` and enable `--with-registry-auth`
Simple Example
```yaml
-name: 'Test Docker Stack Deploy'
+name: 'Stack Deploy Action'
on:
push:
@@ -95,7 +124,7 @@ jobs:
- name: 'Checkout'
uses: actions/checkout@v4
- - name: 'Docker Stack Deploy'
+ - name: 'Stack Deploy'
uses: cssnr/stack-deploy-action@v1
with:
name: 'stack-name'
@@ -109,7 +138,7 @@ jobs:
Full Example
```yaml
-name: 'Test Docker Stack Deploy'
+name: 'Stack Deploy Action'
on:
workflow_dispatch:
@@ -123,43 +152,56 @@ env:
REGISTRY: 'ghcr.io'
jobs:
+ build:
+ name: 'Build'
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+ permissions:
+ packages: write
+
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@v4
+
+ - name: 'Setup Buildx'
+ uses: docker/setup-buildx-action@v2
+ with:
+ platforms: linux/amd64,linux/arm64
+
+ - name: 'Docker Login'
+ uses: docker/login-action@v3
+ with:
+ registry: $${{ env.REGISTRY }}
+ username: ${{ secrets.GHCR_USER }}
+ password: ${{ secrets.GHCR_PASS }}
+
+ - name: 'Generate Tags'
+ id: tags
+ uses: smashedr/docker-tags-action@v1
+ with:
+ images: '$${{ env.REGISTRY }}/${{ github.repository }}'
+ tags: ${{ inputs.tags }}
+
+ - name: 'Build and Push'
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ platforms: linux/amd64,linux/arm64
+ push: true
+ tags: ${{ steps.tags.outputs.tags }}
+ labels: ${{ steps.tags.outputs.labels }}
+
deploy:
name: 'Deploy'
runs-on: ubuntu-latest
timeout-minutes: 5
+ needs: [build]
steps:
- name: 'Checkout'
uses: actions/checkout@v4
- - name: 'Generate Tags'
- id: tags
- uses: smashedr/docker-tags-action@master
- with:
- images: '$${{ env.REGISTRY }}/${{ github.repository }}'
- extra: ${{ inputs.tags }}
-
- - name: 'Setup Buildx'
- uses: docker/setup-buildx-action@v2
- with:
- platforms: linux/amd64,linux/arm64
-
- - name: 'Docker Login'
- uses: docker/login-action@v3
- with:
- registry: $${{ env.REGISTRY }}
- username: ${{ secrets.GHCR_USER }}
- password: ${{ secrets.GHCR_PASS }}
-
- - name: 'Build and Push'
- uses: docker/build-push-action@v6
- with:
- context: .
- platforms: linux/amd64,linux/arm64
- push: true
- tags: ${{ steps.tags.outputs.tags }}
-
- - name: 'Docker Stack Deploy'
+ - name: 'Stack Deploy'
uses: cssnr/stack-deploy-action@v1
with:
name: 'stack-name'
@@ -181,22 +223,25 @@ If you are experiencing an issue/bug or getting unexpected results you can:
- Report an Issue: https://github.com/cssnr/stack-deploy-action/issues
- Chat with us on Discord: https://discord.gg/wXy6m2X8wY
-- Provide General
- Feedback: [https://cssnr.github.io/feedback/](https://cssnr.github.io/feedback/?app=Stack%20Deploy)
+- Provide General Feedback: [https://cssnr.github.io/feedback/](https://cssnr.github.io/feedback/?app=Stack%20Deploy)
# Contributing
Currently, the best way to contribute to this project is to star this project on GitHub.
+If you would like to submit a PR, please review the [CONTRIBUTING.md](CONTRIBUTING.md).
+
Additionally, you can support other GitHub Actions I have published:
-- [VirusTotal Action](https://github.com/cssnr/virustotal-action)
-- [Update Version Tags Action](https://github.com/cssnr/update-version-tags-action)
-- [Update JSON Value Action](https://github.com/cssnr/update-json-value-action)
-- [Parse Issue Form Action](https://github.com/cssnr/parse-issue-form-action)
-- [Mirror Repository Action](https://github.com/cssnr/mirror-repository-action)
-- [Stack Deploy Action](https://github.com/cssnr/stack-deploy-action)
-- [Portainer Stack Deploy](https://github.com/cssnr/portainer-stack-deploy-action)
-- [Mozilla Addon Update Action](https://github.com/cssnr/mozilla-addon-update-action)
+- [Stack Deploy Action](https://github.com/cssnr/stack-deploy-action?tab=readme-ov-file#readme)
+- [Portainer Stack Deploy](https://github.com/cssnr/portainer-stack-deploy-action?tab=readme-ov-file#readme)
+- [VirusTotal Action](https://github.com/cssnr/virustotal-action?tab=readme-ov-file#readme)
+- [Mirror Repository Action](https://github.com/cssnr/mirror-repository-action?tab=readme-ov-file#readme)
+- [Update Version Tags Action](https://github.com/cssnr/update-version-tags-action?tab=readme-ov-file#readme)
+- [Update JSON Value Action](https://github.com/cssnr/update-json-value-action?tab=readme-ov-file#readme)
+- [Parse Issue Form Action](https://github.com/cssnr/parse-issue-form-action?tab=readme-ov-file#readme)
+- [Cloudflare Purge Cache Action](https://github.com/cssnr/cloudflare-purge-cache-action?tab=readme-ov-file#readme)
+- [Mozilla Addon Update Action](https://github.com/cssnr/mozilla-addon-update-action?tab=readme-ov-file#readme)
+- [Docker Tags Action](https://github.com/cssnr/docker-tags-action?tab=readme-ov-file#readme)
For a full list of current projects to support visit: [https://cssnr.github.io/](https://cssnr.github.io/)
diff --git a/action.yaml b/action.yaml
index 787724a..1a8df2a 100644
--- a/action.yaml
+++ b/action.yaml
@@ -22,13 +22,13 @@ inputs:
ssh_key:
description: "SSH Key File"
required: false
- file:
- description: "Docker Compose File"
- default: "docker-compose.yaml"
- required: false
name:
description: "Docker Stack Name"
required: true
+ file:
+ description: "Docker Compose File"
+ required: false
+ default: "docker-compose.yaml"
env_file:
description: "Environment File"
required: false
@@ -44,6 +44,10 @@ inputs:
registry_pass:
description: "Registry Auth Password"
required: false
+ summary:
+ description: "Add Summary to Job"
+ required: false
+ default: "true"
runs:
using: "docker"
diff --git a/event.json b/event.json
new file mode 100644
index 0000000..176cfa8
--- /dev/null
+++ b/event.json
@@ -0,0 +1,3 @@
+{
+ "act": true
+}
diff --git a/src/main.sh b/src/main.sh
index 63e2705..f71ed24 100644
--- a/src/main.sh
+++ b/src/main.sh
@@ -1,79 +1,99 @@
#!/usr/bin/env bash
+# https://github.com/cssnr/stack-deploy-action
set -e
-echo "Running: ${0} as: $(whoami) in: $(pwd)"
-
function cleanup_trap() {
_ST="$?"
if [[ "${_ST}" != "0" ]]; then
- echo -e "\u001b[31;1mScript Exited with Error: ${_ST}"
+ echo -e "โ \u001b[31;1mFailed to deploy stack ${INPUT_NAME}"
+ echo "::error::Failed to deploy stack ${INPUT_NAME}. See logs for details..."
fi
if [ -z "${INPUT_SSH_KEY}" ];then
- echo -e "\u001b[35mCleaning Up authorized_keys on: ${INPUT_HOST}"
- ssh -p "${INPUT_PORT}" "${INPUT_USER}@${INPUT_HOST}" \
+ echo -e "๐งน Cleaning Up authorized_keys"
+ ssh -o BatchMode=yes -o ConnectTimeout=30 -p "${INPUT_PORT}" "${INPUT_USER}@${INPUT_HOST}" \
"sed -i '/docker-stack-deploy-action/d' ~/.ssh/authorized_keys"
fi
if [[ "${_ST}" == "0" ]]; then
- echo -e "\u001b[32;1mFinished Success."
+ echo -e "โ
\u001b[32;1mFinished Success"
fi
exit "${_ST}"
}
-mkdir -p /root/.ssh
-chmod 0700 /root/.ssh
-ssh-keyscan -p "${INPUT_PORT}" -H "${INPUT_HOST}" >> /root/.ssh/known_hosts
+SSH_DIR="/root/.ssh"
+
+echo "::group::Starting Stack Deploy Action"
+echo "User: $(whoami)"
+echo "Script: ${0}"
+echo "Current Directory: $(pwd)"
+echo "Home Directory: ${HOME}"
+echo "SSH Directory: ${SSH_DIR}"
+mkdir -p "${SSH_DIR}" ~/.ssh
+chmod 0700 "${SSH_DIR}" ~/.ssh
+ssh-keyscan -p "${INPUT_PORT}" -H "${INPUT_HOST}" >> "${SSH_DIR}/known_hosts"
+echo "::endgroup::"
if [ -z "${INPUT_SSH_KEY}" ];then
- echo -e "\u001b[36mCreating and Copying SSH Key to: ${INPUT_HOST}"
- ssh-keygen -q -f /root/.ssh/id_rsa -N "" -C "docker-stack-deploy-action"
+ echo -e "::group::Copying SSH Key to Remote Host"
+ ssh-keygen -q -f "${SSH_DIR}/id_rsa" -N "" -C "docker-stack-deploy-action"
eval "$(ssh-agent -s)"
- ssh-add /root/.ssh/id_rsa
-
- sshpass -p "${INPUT_PASS}" \
- ssh-copy-id -p "${INPUT_PORT}" -i /root/.ssh/id_rsa \
- "${INPUT_USER}@${INPUT_HOST}"
+ ssh-add "${SSH_DIR}/id_rsa"
+ sshpass -eINPUT_PASS \
+ ssh-copy-id -i "${SSH_DIR}/id_rsa" -o ConnectTimeout=30 \
+ -p "${INPUT_PORT}" "${INPUT_USER}@${INPUT_HOST}"
else
- echo -e "\u001b[36mAdding SSH Key to SSH Agent"
- echo "${INPUT_SSH_KEY}" > /root/.ssh/id_rsa
- chmod 0600 /root/.ssh/id_rsa
+ echo "::group::Adding SSH Key to SSH Agent"
+ echo "${INPUT_SSH_KEY}" > "${SSH_DIR}/id_rsa"
+ chmod 0600 "${SSH_DIR}/id_rsa"
eval "$(ssh-agent -s)"
- ssh-add /root/.ssh/id_rsa
+ ssh-add "${SSH_DIR}/id_rsa"
fi
+echo "::endgroup::"
trap cleanup_trap EXIT HUP INT QUIT PIPE TERM
-echo -e "\u001b[36mVerifying Docker and Setting Context."
-ssh -p "${INPUT_PORT}" "${INPUT_USER}@${INPUT_HOST}" "docker info" > /dev/null
-
+echo "::group::Verifying Remote Docker Context"
+ssh -o BatchMode=yes -o ConnectTimeout=30 -p "${INPUT_PORT}" \
+ "${INPUT_USER}@${INPUT_HOST}" "docker info" > /dev/null
if ! docker context inspect remote >/dev/null 2>&1;then
docker context create remote --docker "host=ssh://${INPUT_USER}@${INPUT_HOST}:${INPUT_PORT}"
fi
docker context use remote
docker context ls
+echo "::endgroup::"
if [ -n "${INPUT_ENV_FILE}" ];then
- echo -e "\u001b[36mSourcing Environment File: \u001b[37;1m${INPUT_ENV_FILE}"
+ echo -e "::group::Sourcing Environment File: \u001b[36;1m${INPUT_ENV_FILE}"
stat "${INPUT_ENV_FILE}"
set -a
# shellcheck disable=SC1090
source "${INPUT_ENV_FILE}"
- # echo TRAEFIK_HOST: "${TRAEFIK_HOST}"
- # export ENV_FILE="${INPUT_ENV_FILE}"
+echo "::endgroup::"
fi
if [[ -n "${INPUT_REGISTRY_USER}" && -n "${INPUT_REGISTRY_PASS}" ]];then
- echo -e "\u001b[36mLogging in to Registry: \u001b[37;1m${INPUT_REGISTRY_HOST:-Docker Hub}"
+ echo -e "::group::Logging in to Registry: \u001b[36;1m${INPUT_REGISTRY_HOST:-Docker Hub}"
echo "${INPUT_REGISTRY_PASS}" |
docker login --username "${INPUT_REGISTRY_USER}" --password-stdin "${INPUT_REGISTRY_HOST}"
INPUT_REGISTRY_AUTH="true"
+ echo "::endgroup::"
fi
+echo -e "::group::Deploying Stack: \u001b[36;1m${INPUT_NAME}"
EXTRA_ARGS=()
if [[ -n "${INPUT_REGISTRY_AUTH}" ]];then
- echo -e "Adding extra arg: --with-registry-auth"
+ echo -e "Adding: --with-registry-auth"
EXTRA_ARGS+=("--with-registry-auth")
fi
+# shellcheck disable=SC2034
+STACK_RESULTS=$(docker stack deploy -c "${INPUT_FILE}" "${INPUT_NAME}" "${EXTRA_ARGS[@]}")
+echo "::endgroup::"
+
+echo "${STACK_RESULTS}"
-echo -e "\u001b[36mDeploying Stack: \u001b[37;1m${INPUT_NAME}"
-docker stack deploy -c "${INPUT_FILE}" "${INPUT_NAME}" "${EXTRA_ARGS[@]}"
+if [[ "${INPUT_SUMMARY}" == "true" ]];then
+ echo "๐ Writing Job Summary"
+ # shellcheck source=/src/summary.sh
+ source /src/summary.sh >> "${GITHUB_STEP_SUMMARY}" ||\
+ echo "::error::Failed to Write Job Summary!"
+fi
diff --git a/src/summary.sh b/src/summary.sh
new file mode 100644
index 0000000..b9e1ba5
--- /dev/null
+++ b/src/summary.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+cat << EOM
+## Stack Deploy Action
+
+๐ Stack \`${INPUT_NAME}\` Successfully Deployed.
+
+Results
+
+\`\`\`text
+${STACK_RESULTS}
+\`\`\`
+
+
+
+[Report an issue or request a feature](https://github.com/cssnr/stack-deploy-action?tab=readme-ov-file#readme)
+EOM