From ba3636f01c21335d9dc17aa0ca52a10b21ac6aad Mon Sep 17 00:00:00 2001 From: Joseph Ezekiel Date: Sun, 14 Dec 2025 11:35:02 +0100 Subject: [PATCH 1/3] Fix: Support multiple compose files in swarm mode - Added file splitting logic for swarm mode (similar to compose mode) - Each file now gets its own -c flag in swarm deployments - Fixes issue where multiple files were treated as a single filename Before: docker stack deploy -c \"file1 file2\" stack-name After: docker stack deploy -c file1 -c file2 stack-name --- .github/workflows/test.yaml | 42 +++++++++++++++++++++++++++++++++++++ README.md | 39 ++++++++++++++++++++++++++++------ src/main.sh | 13 ++++++++---- 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8f725b1..0c07d38 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -130,6 +130,48 @@ jobs: registry_user: ${{ vars.DOCKER_HUB_USER }} registry_pass: ${{ secrets.DOCKER_HUB_PASS }} + - name: "5: Write Base YAML" + if: ${{ !cancelled() }} + uses: teunmooij/yaml@v1 + with: + to-file: "docker-compose.base.yaml" + data: | + {"version":"3.8","services":{"alpine":{"image":"alpine:latest","command":"tail -f /dev/null"}}} + + - name: "5: Write Override YAML" + if: ${{ !cancelled() }} + uses: teunmooij/yaml@v1 + with: + to-file: "docker-compose.override.yaml" + data: | + {"version":"3.8","services":{"alpine":{"environment":{"TEST":"multiple-files"}}}} + + - name: "5: Test Multiple Files (Swarm)" + if: ${{ !cancelled() }} + uses: ./ + with: + name: test_stack-deploy-multi + file: docker-compose.base.yaml docker-compose.override.yaml + host: ${{ secrets.DOCKER_HOST }} + port: ${{ secrets.DOCKER_PORT }} + user: ${{ secrets.DOCKER_USER }} + ssh_key: ${{ secrets.DOCKER_SSH_KEY }} + detach: false + resolve_image: "changed" + + - name: "6: Test Multiple Files (Compose)" + if: ${{ !cancelled() }} + uses: ./ + with: + name: test_stack-deploy-compose-multi + file: docker-compose.base.yaml docker-compose.override.yaml + host: ${{ secrets.DOCKER_HOST }} + port: ${{ secrets.DOCKER_PORT }} + user: ${{ secrets.DOCKER_USER }} + ssh_key: ${{ secrets.DOCKER_SSH_KEY }} + mode: compose + summary: false + - name: "Schedule Failure Notification" if: ${{ failure() && github.event_name == 'schedule' }} uses: sarisia/actions-status-discord@v1 diff --git a/README.md b/README.md index 18f7464..e731d62 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ You can also view an [Action Comparison](https://docker-deploy.cssnr.com/guides/ | Input Name | Default Value | Short Description of the Input Value | | :------------------- | :---------------------------------- | :----------------------------------------------------------------- | | `name` | _Required_ | Docker Stack/Project Name [⤵️](#name) | -| `file` | `docker-compose.yaml` | Docker Stack/Compose File(s) [⤵️](#file) | +| `file` | `docker-compose.yaml` | Docker Stack/Compose File(s) (supports multiple) [⤵️](#file) | | `mode`**¹** | `swarm` | Deploy Mode [`swarm`, `compose`] [⤵️](#mode) | | `args`**¹** | `--remove-orphans --force-recreate` | Additional **Compose** Arguments [⤵️](#args) | | `host` | _Required_ | Remote Docker Hostname or IP [⤵️](#host) | @@ -126,18 +126,21 @@ You can also view an [Action Comparison](https://docker-deploy.cssnr.com/guides/ > \* More details below...
📟 Click Here to see how the deployment command is generated - ```shell if [[ "${INPUT_MODE}" == "swarm" ]];then DEPLOY_TYPE="Swarm" - COMMAND=("docker" "stack" "deploy" "-c" "${INPUT_FILE}" "${EXTRA_ARGS[@]}" "${INPUT_NAME}") + COMMAND=("docker" "stack" "deploy" "${STACK_FILES[@]}" "${EXTRA_ARGS[@]}" "${INPUT_NAME}") else DEPLOY_TYPE="Compose" COMMAND=("docker" "compose" "${STACK_FILES[@]}" "-p" "${INPUT_NAME}" "up" "-d" "-y" "${EXTRA_ARGS[@]}") fi ``` -Compose Note: `"${STACK_FILES[@]}"` is an array of `-f docker-compose.yaml` for every `file` in the argument. +**Note:** `"${STACK_FILES[@]}"` is an array of file paths with the appropriate flag prepended: +- **Swarm mode:** `-c file1.yaml -c file2.yaml` for each file +- **Compose mode:** `-f file1.yaml -f file2.yaml` for each file + +Files are processed in the order provided and merged, with later files overriding earlier ones. If you need more control over the deployment command or have a complex deployment, see the [Docker Context Action](https://github.com/cssnr/docker-context-action?tab=readme-ov-file#readme). @@ -152,8 +155,13 @@ Stack name for Swarm and project name for Compose. #### file -Stack file or Compose file(s). Multiple files can be provided, space seperated, and a `-f` will be prepended to each. -Example: `web.yaml db.yaml`. +Stack file or Compose file(s). Multiple files can be provided, space-separated, and a `-c` flag (for swarm) or `-f` flag (for compose) will be prepended to each file. + +**Examples:** +- Single file: `docker-compose.yaml` +- Multiple files: `base.yaml production.yaml` + +**Note:** Files are merged in order, with later files overriding earlier ones. #### mode @@ -381,9 +389,28 @@ Additional [Examples](https://docker-deploy.cssnr.com/guides/examples) are avail args: --remove-orphans --force-recreate ``` + Note: these are the default arguments. If you use `args` this will override the default arguments unless they are included. You can disable them by passing an empty string. For more details, see the compose up [docs](https://docs.docker.com/reference/cli/docker/compose/up/). +
Multiple Compose Files (Swarm Mode) + +Deploy with a base configuration and environment-specific overrides: +```yaml +- name: 'Stack Deploy' + uses: cssnr/stack-deploy-action@v1 + with: + name: 'my-stack' + file: 'docker-compose.base.yaml docker-compose.production.yaml' + host: ${{ secrets.DOCKER_HOST }} + user: ${{ secrets.DOCKER_USER }} + ssh_key: ${{ secrets.DOCKER_SSH_KEY }} +``` + +This will merge the files in order, with `docker-compose.production.yaml` overriding values from `docker-compose.base.yaml`. + +
+
Compose with Private Image diff --git a/src/main.sh b/src/main.sh index 459ce15..aec4611 100644 --- a/src/main.sh +++ b/src/main.sh @@ -164,21 +164,26 @@ fi echo "::debug::EXTRA_ARGS: ${EXTRA_ARGS[*]}" ## Collect Stack Files - +STACK_FILES=() if [[ "${INPUT_MODE}" == "compose" ]];then - STACK_FILES=() read -r -a files <<< "${INPUT_FILE}" for file in "${files[@]}";do STACK_FILES+=("-f" "$file") done - echo "::debug::STACK_FILES: ${STACK_FILES[*]}" + echo "::debug::COMPOSE STACK_FILES: ${STACK_FILES[*]}" +elif [[ "${INPUT_MODE}" == "swarm" ]];then + read -r -a files <<< "${INPUTE_FILE}" + for file in "${files[@]}";do + STACK_FILES+=("-c" "$file") + done + echo "::debug::SWARM STACK_FILES: ${STACK_FILES[*]}" fi ## Deploy Stack if [[ "${INPUT_MODE}" == "swarm" ]];then DEPLOY_TYPE="Swarm" - COMMAND=("docker" "stack" "deploy" "-c" "${INPUT_FILE}" "${EXTRA_ARGS[@]}" "${INPUT_NAME}") + COMMAND=("docker" "stack" "deploy" "${STACK_FILES[@]}" "${EXTRA_ARGS[@]}" "${INPUT_NAME}") else DEPLOY_TYPE="Compose" COMMAND=("docker" "compose" "${STACK_FILES[@]}" "-p" "${INPUT_NAME}" "up" "-d" "-y" "${EXTRA_ARGS[@]}") From 353e60e041b3533d917bfac4edace27e11d5fed2 Mon Sep 17 00:00:00 2001 From: Joseph Ezekiel Date: Sun, 14 Dec 2025 11:44:25 +0100 Subject: [PATCH 2/3] fix syntax issue in main --- src/main.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.sh b/src/main.sh index aec4611..b2bda75 100644 --- a/src/main.sh +++ b/src/main.sh @@ -165,6 +165,7 @@ echo "::debug::EXTRA_ARGS: ${EXTRA_ARGS[*]}" ## Collect Stack Files STACK_FILES=() + if [[ "${INPUT_MODE}" == "compose" ]];then read -r -a files <<< "${INPUT_FILE}" for file in "${files[@]}";do @@ -172,7 +173,7 @@ if [[ "${INPUT_MODE}" == "compose" ]];then done echo "::debug::COMPOSE STACK_FILES: ${STACK_FILES[*]}" elif [[ "${INPUT_MODE}" == "swarm" ]];then - read -r -a files <<< "${INPUTE_FILE}" + read -r -a files <<< "${INPUT_FILE}" for file in "${files[@]}";do STACK_FILES+=("-c" "$file") done From e8b5e09472142ffc556052b08177f898a1ece806 Mon Sep 17 00:00:00 2001 From: Joseph Ezekiel Date: Sun, 14 Dec 2025 20:10:25 +0100 Subject: [PATCH 3/3] docs: format README w/Prettier --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e731d62..7af1912 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ You can also view an [Action Comparison](https://docker-deploy.cssnr.com/guides/ | Input Name | Default Value | Short Description of the Input Value | | :------------------- | :---------------------------------- | :----------------------------------------------------------------- | | `name` | _Required_ | Docker Stack/Project Name [⤵️](#name) | -| `file` | `docker-compose.yaml` | Docker Stack/Compose File(s) (supports multiple) [⤵️](#file) | +| `file` | `docker-compose.yaml` | Docker Stack/Compose File(s) (supports multiple) [⤵️](#file) | | `mode`**¹** | `swarm` | Deploy Mode [`swarm`, `compose`] [⤵️](#mode) | | `args`**¹** | `--remove-orphans --force-recreate` | Additional **Compose** Arguments [⤵️](#args) | | `host` | _Required_ | Remote Docker Hostname or IP [⤵️](#host) | @@ -137,6 +137,7 @@ fi ``` **Note:** `"${STACK_FILES[@]}"` is an array of file paths with the appropriate flag prepended: + - **Swarm mode:** `-c file1.yaml -c file2.yaml` for each file - **Compose mode:** `-f file1.yaml -f file2.yaml` for each file @@ -158,6 +159,7 @@ Stack name for Swarm and project name for Compose. Stack file or Compose file(s). Multiple files can be provided, space-separated, and a `-c` flag (for swarm) or `-f` flag (for compose) will be prepended to each file. **Examples:** + - Single file: `docker-compose.yaml` - Multiple files: `base.yaml production.yaml` @@ -389,13 +391,13 @@ Additional [Examples](https://docker-deploy.cssnr.com/guides/examples) are avail args: --remove-orphans --force-recreate ``` - Note: these are the default arguments. If you use `args` this will override the default arguments unless they are included. You can disable them by passing an empty string. For more details, see the compose up [docs](https://docs.docker.com/reference/cli/docker/compose/up/).
Multiple Compose Files (Swarm Mode) Deploy with a base configuration and environment-specific overrides: + ```yaml - name: 'Stack Deploy' uses: cssnr/stack-deploy-action@v1