mirror of
https://github.com/hoverkraft-tech/compose-action.git
synced 2026-01-10 22:53:06 +08:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05da55b2bb | ||
|
|
d66307f735 | ||
|
|
d6adfd48d3 | ||
|
|
3086829978 | ||
|
|
9dc1f1e6ec | ||
|
|
50a58965b3 | ||
|
|
b7900497f3 | ||
|
|
089c512a98 | ||
|
|
b63643de22 | ||
|
|
248470ecc5 | ||
|
|
5d59cf29d8 | ||
|
|
e9bb59d794 | ||
|
|
6724232075 | ||
|
|
f1193bc509 | ||
|
|
175bf4a061 | ||
|
|
9974256204 | ||
|
|
2c655a3602 | ||
|
|
2feed3a086 | ||
|
|
0c4c8ad01b | ||
|
|
0683632a02 | ||
|
|
d626027cf5 | ||
|
|
6e0a504521 | ||
|
|
ccd64b05f8 | ||
|
|
ee80f8a42f |
@ -1,42 +1,29 @@
|
|||||||
{
|
{
|
||||||
"name": "GitHub Actions (TypeScript)",
|
"name": "Debian",
|
||||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:20",
|
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
|
||||||
"postCreateCommand": "npm install",
|
"features": {
|
||||||
"customizations": {
|
"ghcr.io/devcontainers/features/node:1": {},
|
||||||
"codespaces": {
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
||||||
"openFiles": ["README.md"]
|
"ghcr.io/devcontainers/features/github-cli:1": {}
|
||||||
},
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"bierner.markdown-preview-github-styles",
|
|
||||||
"davidanson.vscode-markdownlint",
|
|
||||||
"dbaeumer.vscode-eslint",
|
|
||||||
"esbenp.prettier-vscode",
|
|
||||||
"github.copilot",
|
|
||||||
"github.copilot-chat",
|
|
||||||
"github.vscode-github-actions",
|
|
||||||
"github.vscode-pull-request-github",
|
|
||||||
"me-dutour-mathieu.vscode-github-actions",
|
|
||||||
"redhat.vscode-yaml",
|
|
||||||
"rvest.vs-code-prettier-eslint",
|
|
||||||
"yzhang.markdown-all-in-one"
|
|
||||||
],
|
|
||||||
"settings": {
|
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"markdown.extension.list.indentationSize": "adaptive",
|
|
||||||
"markdown.extension.italic.indicator": "_",
|
|
||||||
"markdown.extension.orderedList.marker": "one"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"remoteEnv": {
|
"remoteEnv": {
|
||||||
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
|
"GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}"
|
||||||
},
|
},
|
||||||
"features": {
|
"customizations": {
|
||||||
"ghcr.io/devcontainers/features/github-cli:1": {},
|
"vscode": {
|
||||||
"ghcr.io/devcontainers-community/npm-features/prettier:1": {},
|
"extensions": [
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
"eamodio.gitlens",
|
||||||
|
"github.copilot",
|
||||||
|
"github.copilot-chat",
|
||||||
|
"github.vscode-github-actions",
|
||||||
|
"ms-vscode.makefile-tools",
|
||||||
|
"bierner.markdown-preview-github-styles",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"esbenp.prettier-vscode"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.defaultProfile.linux": "zsh"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
.github/dependabot.yml
vendored
8
.github/dependabot.yml
vendored
@ -47,11 +47,11 @@ updates:
|
|||||||
day: friday
|
day: friday
|
||||||
time: "04:00"
|
time: "04:00"
|
||||||
groups:
|
groups:
|
||||||
|
npm-dev-dependencies:
|
||||||
|
dependency-type: development
|
||||||
actions-dependencies:
|
actions-dependencies:
|
||||||
patterns:
|
patterns:
|
||||||
- "@actions/*"
|
- "@actions/*"
|
||||||
npm-dev-dependencies:
|
|
||||||
dependency-type: development
|
|
||||||
|
|
||||||
- package-ecosystem: "devcontainers"
|
- package-ecosystem: "devcontainers"
|
||||||
open-pull-requests-limit: 20
|
open-pull-requests-limit: 20
|
||||||
@ -60,7 +60,3 @@ updates:
|
|||||||
interval: weekly
|
interval: weekly
|
||||||
day: friday
|
day: friday
|
||||||
time: "04:00"
|
time: "04:00"
|
||||||
groups:
|
|
||||||
devcontainers-dependencies:
|
|
||||||
patterns:
|
|
||||||
- "*"
|
|
||||||
|
|||||||
2
.github/linters/.jscpd.json
vendored
2
.github/linters/.jscpd.json
vendored
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"ignore": ["**/dist/**"]
|
"ignore": ["**/dist/**", "**/node_modules/**", "**/coverage/**"]
|
||||||
}
|
}
|
||||||
|
|||||||
30
.github/release-config.yml
vendored
Normal file
30
.github/release-config.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
template: |
|
||||||
|
# What's Changed
|
||||||
|
$CHANGES
|
||||||
|
**Full Changelog**: https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...$RESOLVED_VERSION
|
||||||
|
name-template: "Version $RESOLVED_VERSION"
|
||||||
|
tag-template: "$RESOLVED_VERSION"
|
||||||
|
tag-prefix: ""
|
||||||
|
prerelease-identifier: "rc"
|
||||||
|
version-resolver:
|
||||||
|
major:
|
||||||
|
labels:
|
||||||
|
- "release-major"
|
||||||
|
minor:
|
||||||
|
labels:
|
||||||
|
- "release-minor"
|
||||||
|
patch:
|
||||||
|
labels:
|
||||||
|
- "release-patch"
|
||||||
|
default: patch
|
||||||
|
autolabeler:
|
||||||
|
- label: "release-major"
|
||||||
|
title:
|
||||||
|
- "/^BREAKING CHANGE:/"
|
||||||
|
- "/^\\w+!:/"
|
||||||
|
- "/^\\w+\\(.+\\)!:/"
|
||||||
|
- label: "release-minor"
|
||||||
|
title:
|
||||||
|
- "/^feat:/"
|
||||||
|
- "/^feat\\(.+\\):/"
|
||||||
382
.github/workflows/__check-action.yml
vendored
382
.github/workflows/__check-action.yml
vendored
@ -3,222 +3,193 @@ name: Internal - Tests for action
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-action-with-services:
|
test-action:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Test with services
|
name: ${{ matrix.name }} - ${{ matrix.assertion-name }}
|
||||||
steps:
|
permissions:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
contents: read
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: Given multiple services when filtering services
|
||||||
|
assertion-name: "Then only expected services run"
|
||||||
|
compose-file: ./test/docker-compose.yml
|
||||||
|
services: |
|
||||||
|
service-b
|
||||||
|
service-c
|
||||||
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose.yml ps
|
||||||
|
|
||||||
- name: Act
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
||||||
uses: ./
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 || (echo "Service service-c is not running" && exit 1)
|
||||||
with:
|
(docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
||||||
compose-file: "./test/docker-compose.yml"
|
|
||||||
services: |
|
|
||||||
service-b
|
|
||||||
service-c
|
|
||||||
|
|
||||||
- name: "Assert: only expected services are running"
|
- name: Given compose file when applying down flags
|
||||||
run: |
|
assertion-name: "Then teardown honors down flags"
|
||||||
docker compose -f ./test/docker-compose.yml ps
|
compose-file: ./test/docker-compose.yml
|
||||||
|
down-flags: "--volumes"
|
||||||
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose.yml ps
|
||||||
|
|
||||||
docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 || (echo "Service service-a is not running" && exit 1)
|
||||||
docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 || (echo "Service service-c is not running" && exit 1)
|
(docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 && echo "Service service-b should not be running without profile" && exit 1) || true
|
||||||
(docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
(docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 && echo "Service service-c should not be running without profile" && exit 1) || true
|
||||||
|
|
||||||
test-action-with-down-flags:
|
- name: Given compose profile when passing compose flags
|
||||||
runs-on: ubuntu-latest
|
assertion-name: "Then the requested profile is active"
|
||||||
name: Test compose action
|
compose-file: ./test/docker-compose.yml
|
||||||
steps:
|
compose-flags: "--profile profile-1"
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
down-flags: "--volumes"
|
||||||
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose.yml -p profile-1 ps || (echo "Profile not used" && exit 1)
|
||||||
|
|
||||||
- name: Act
|
- name: Given image supplied via env when running action
|
||||||
uses: ./
|
assertion-name: "Then compose uses the provided env"
|
||||||
with:
|
compose-file: ./test/docker-compose-with-env.yml
|
||||||
compose-file: "./test/docker-compose.yml"
|
image-name: busybox
|
||||||
down-flags: "--volumes"
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose-with-env.yml ps
|
||||||
|
|
||||||
test-action-with-compose-flags:
|
docker compose -f ./test/docker-compose-with-env.yml ps | grep test-service-a-1 || (echo "Service service-a is not running" && exit 1)
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with compose flags
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: Act
|
- name: Given multiple compose files when selecting services
|
||||||
uses: ./
|
assertion-name: "Then only services from selection run"
|
||||||
with:
|
compose-file: |
|
||||||
compose-file: "./test/docker-compose.yml"
|
./test/docker-compose.yml
|
||||||
compose-flags: "--profile profile-1"
|
./test/docker-compose.ci.yml
|
||||||
down-flags: "--volumes"
|
services: |
|
||||||
|
service-b
|
||||||
|
service-d
|
||||||
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps
|
||||||
|
|
||||||
- name: "Assert: profile is used"
|
docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
||||||
run: |
|
docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-d-1 || (echo "Service service-d is not running" && exit 1)
|
||||||
docker compose -f ./test/docker-compose.yml -p profile-1 ps || (echo "Profile not used" && exit 1)
|
(docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
||||||
|
(docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-c-1 && echo "Unexpected service service-c is running" && exit 1) || true
|
||||||
|
|
||||||
test-action-with-env:
|
- name: Given compose file in subdirectory when setting cwd
|
||||||
runs-on: ubuntu-latest
|
assertion-name: "Then only expected services run"
|
||||||
name: Test with env
|
compose-file: docker-compose.yml
|
||||||
steps:
|
cwd: ./test
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
services: |
|
||||||
|
service-b
|
||||||
|
service-c
|
||||||
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose.yml ps
|
||||||
|
|
||||||
- name: Act
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
||||||
uses: ./
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 || (echo "Service service-c is not running" && exit 1)
|
||||||
with:
|
(docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
||||||
compose-file: "./test/docker-compose-with-env.yml"
|
|
||||||
env:
|
|
||||||
IMAGE_NAME: busybox
|
|
||||||
|
|
||||||
- name: "Assert: env is used"
|
- name: Given absolute compose path when running action
|
||||||
env:
|
assertion-name: "Then only expected services run"
|
||||||
IMAGE_NAME: busybox
|
compose-file: test/docker-compose.yml
|
||||||
run: |
|
use-absolute-path: true
|
||||||
docker compose -f ./test/docker-compose-with-env.yml ps
|
services: |
|
||||||
|
service-b
|
||||||
|
service-c
|
||||||
|
assertion: |
|
||||||
|
docker compose -f ./test/docker-compose.yml ps
|
||||||
|
|
||||||
docker compose -f ./test/docker-compose-with-env.yml ps | grep test-service-a-1 || (echo "Service service-a is not running" && exit 1)
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
||||||
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 || (echo "Service service-c is not running" && exit 1)
|
||||||
|
(docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
||||||
|
|
||||||
test-action-with-multiple-compose-files:
|
- name: Given compose with multiple services when using abort-on-container-exit
|
||||||
runs-on: ubuntu-latest
|
assertion-name: "Then execution stops on container exit"
|
||||||
name: Test with multiple compose files
|
compose-file: test/docker-compose-web-mysql.yml
|
||||||
steps:
|
up-flags: "--build --abort-on-container-exit --exit-code-from=web"
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
assertion: |
|
||||||
|
WEB_EXIT_CODE=$(docker compose -f ./test/docker-compose-web-mysql.yml ps web --all --format json | jq ".ExitCode")
|
||||||
|
[ "$WEB_EXIT_CODE" == "0" ] || (echo "Web service did not exit successfully" && exit 1)
|
||||||
|
|
||||||
- name: Act
|
MYSQL_STATE=$(docker compose -f ./test/docker-compose-web-mysql.yml ps mysql --all --format json | jq -r ".State")
|
||||||
uses: ./
|
if [ "$MYSQL_STATE" = "running" ]; then
|
||||||
with:
|
echo "MySQL service is still running"
|
||||||
compose-file: |
|
exit 1
|
||||||
./test/docker-compose.yml
|
fi
|
||||||
./test/docker-compose.ci.yml
|
|
||||||
services: |
|
|
||||||
service-b
|
|
||||||
service-d
|
|
||||||
|
|
||||||
- name: "Assert: only expected services are running"
|
- name: Given failing dependency when attaching dependencies
|
||||||
run: |
|
assertion-name: "Then failing service exits with code 1"
|
||||||
docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps
|
compose-file: test/docker-compose-fail.yml
|
||||||
|
up-flags: "--attach-dependencies"
|
||||||
|
assertion: |
|
||||||
|
EXIT_CODE=$(docker compose -f ./test/docker-compose-fail.yml ps service-a --all --format json | jq ".ExitCode")
|
||||||
|
[ "$EXIT_CODE" == "1" ] || (echo "Service service-a did not exit with code 1" && exit 1)
|
||||||
|
|
||||||
docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
- name: Given compose version mismatch when requesting explicit version
|
||||||
docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-d-1 || (echo "Service service-d is not running" && exit 1)
|
assertion-name: "Then docker compose reports the requested version"
|
||||||
(docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
compose-file: ./test/docker-compose.yml
|
||||||
(docker compose -f ./test/docker-compose.yml -f ./test/docker-compose.ci.yml ps | grep test-service-c-1 && echo "Unexpected service service-c is running" && exit 1) || true
|
compose-version: "2.29.0"
|
||||||
|
expected-compose-version: "2.29.0"
|
||||||
|
ensure-version-mismatch: true
|
||||||
|
assertion: |
|
||||||
|
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
||||||
|
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
||||||
|
|
||||||
test-action-with-cwd:
|
if [ "$CURRENT_DOCKER_COMPOSE_VERSION" != "$DOCKER_COMPOSE_VERSION" ]; then
|
||||||
runs-on: ubuntu-latest
|
echo "Docker compose version is not in $DOCKER_COMPOSE_VERSION version"
|
||||||
name: Test with cwd
|
exit 1
|
||||||
steps:
|
fi
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: Act
|
- name: Given compose version mismatch when requesting latest version
|
||||||
uses: ./
|
assertion-name: "Then docker compose reports the requested version"
|
||||||
with:
|
compose-file: ./test/docker-compose.yml
|
||||||
compose-file: "docker-compose.yml"
|
compose-version: latest
|
||||||
cwd: "./test"
|
fetch-latest-compose: true
|
||||||
services: |
|
ensure-version-mismatch: true
|
||||||
service-b
|
assertion: |
|
||||||
service-c
|
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
||||||
|
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
||||||
|
|
||||||
- name: "Assert: only expected services are running"
|
if [ "$CURRENT_DOCKER_COMPOSE_VERSION" != "$DOCKER_COMPOSE_VERSION" ]; then
|
||||||
run: |
|
echo "Docker compose version is not in $DOCKER_COMPOSE_VERSION version"
|
||||||
docker compose -f ./test/docker-compose.yml ps
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
- name: Given custom docker context when providing docker flags
|
||||||
docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 || (echo "Service service-c is not running" && exit 1)
|
assertion-name: "Then docker compose uses that context"
|
||||||
(docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
compose-file: ./test/docker-compose.yml
|
||||||
|
compose-version: latest
|
||||||
|
docker-flags: "--context test-context"
|
||||||
|
docker-context: test-context
|
||||||
|
assertion: |
|
||||||
|
CURRENT_CONTEXT=$(docker context show)
|
||||||
|
if [ "$CURRENT_CONTEXT" != "test-context" ]; then
|
||||||
|
echo "Docker context is '$CURRENT_CONTEXT' instead of 'test-context'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
test-action-with-absolute-path:
|
docker compose -f ./test/docker-compose.yml ps
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with absolute path
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: Act
|
docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 || (echo "Service service-a is not running under custom context" && exit 1)
|
||||||
uses: ./
|
(docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 && echo "Service service-b should not be running without profile" && exit 1) || true
|
||||||
with:
|
|
||||||
compose-file: "${{ github.workspace }}/test/docker-compose.yml"
|
|
||||||
services: |
|
|
||||||
service-b
|
|
||||||
service-c
|
|
||||||
|
|
||||||
- name: "Assert: only expected services are running"
|
|
||||||
run: |
|
|
||||||
docker compose -f ./test/docker-compose.yml ps
|
|
||||||
|
|
||||||
docker compose -f ./test/docker-compose.yml ps | grep test-service-b-1 || (echo "Service service-b is not running" && exit 1)
|
|
||||||
docker compose -f ./test/docker-compose.yml ps | grep test-service-c-1 || (echo "Service service-c is not running" && exit 1)
|
|
||||||
(docker compose -f ./test/docker-compose.yml ps | grep test-service-a-1 && echo "Unexpected service service-a is running" && exit 1) || true
|
|
||||||
|
|
||||||
test-abort-on-container-exit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with --abort-on-container-exit
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: Act
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
compose-file: "test/docker-compose-web-mysql.yml"
|
|
||||||
up-flags: "--build --abort-on-container-exit --exit-code-from=web"
|
|
||||||
|
|
||||||
test-attach-dependencies-failure:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with --attach-dependencies and service failure
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: Act
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
compose-file: "test/docker-compose-fail.yml"
|
|
||||||
up-flags: "--attach-dependencies"
|
|
||||||
|
|
||||||
- name: Assert
|
|
||||||
run: |
|
|
||||||
EXIT_CODE=$(docker compose -f ./test/docker-compose-fail.yml ps service-a --all --format json | jq ".ExitCode")
|
|
||||||
[ "$EXIT_CODE" == "1" ] || (echo "Service service-a did not exit with code 1" && exit 1)
|
|
||||||
|
|
||||||
test-action-with-compose-version:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with compose version
|
|
||||||
env:
|
env:
|
||||||
DOCKER_COMPOSE_VERSION: "2.29.0"
|
DOCKER_COMPOSE_VERSION: ${{ matrix.expected-compose-version || '' }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
|
||||||
- name: "Arrange: ensure original docker compose version is not the expected one"
|
|
||||||
run: |
|
|
||||||
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
|
||||||
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
|
||||||
|
|
||||||
if [ "$CURRENT_DOCKER_COMPOSE_VERSION" == "$DOCKER_COMPOSE_VERSION" ]; then
|
|
||||||
echo "Docker compose version is already in $DOCKER_COMPOSE_VERSION version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Act
|
|
||||||
uses: ./
|
|
||||||
with:
|
with:
|
||||||
compose-file: "./test/docker-compose.yml"
|
persist-credentials: false
|
||||||
compose-version: "2.29.0"
|
|
||||||
|
|
||||||
- name: "Assert: compose version is used"
|
- name: Set up Docker context
|
||||||
run: |
|
if: ${{ matrix.docker-context }}
|
||||||
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
uses: docker/setup-docker-action@e61617a16c407a86262fb923c35a616ddbe070b3 # v4.6.0
|
||||||
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
with:
|
||||||
|
context: ${{ matrix.docker-context }}
|
||||||
|
|
||||||
if [ "$CURRENT_DOCKER_COMPOSE_VERSION" != "$DOCKER_COMPOSE_VERSION" ]; then
|
- name: Resolve absolute compose path
|
||||||
echo "Docker compose version is not in $DOCKER_COMPOSE_VERSION version"
|
if: ${{ matrix.use-absolute-path }}
|
||||||
exit 1
|
id: compose-path
|
||||||
fi
|
run: echo "absolute=${GITHUB_WORKSPACE}/${{ matrix.compose-file }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
test-action-with-compose-version-latest:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with compose version latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: "Arrange: retrieve latest version of docker compose"
|
- name: "Arrange: retrieve latest version of docker compose"
|
||||||
|
if: ${{ matrix.fetch-latest-compose }}
|
||||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
@ -230,6 +201,7 @@ jobs:
|
|||||||
core.exportVariable('DOCKER_COMPOSE_VERSION', dockerComposeVersion);
|
core.exportVariable('DOCKER_COMPOSE_VERSION', dockerComposeVersion);
|
||||||
|
|
||||||
- name: "Arrange: ensure original docker compose version is not the expected one"
|
- name: "Arrange: ensure original docker compose version is not the expected one"
|
||||||
|
if: ${{ matrix.ensure-version-mismatch }}
|
||||||
run: |
|
run: |
|
||||||
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
||||||
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
||||||
@ -242,33 +214,19 @@ jobs:
|
|||||||
- name: Act
|
- name: Act
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
compose-file: "./test/docker-compose.yml"
|
compose-file: ${{ matrix.use-absolute-path && steps.compose-path.outputs.absolute || matrix.compose-file }}
|
||||||
compose-version: "latest"
|
services: ${{ matrix.services || '' }}
|
||||||
|
down-flags: ${{ matrix.down-flags || '' }}
|
||||||
|
compose-flags: ${{ matrix.compose-flags || '' }}
|
||||||
|
compose-version: ${{ matrix.compose-version || '' }}
|
||||||
|
cwd: ${{ matrix.cwd || '' }}
|
||||||
|
up-flags: ${{ matrix.up-flags || '' }}
|
||||||
|
docker-flags: ${{ matrix.docker-flags || '' }}
|
||||||
|
env:
|
||||||
|
IMAGE_NAME: ${{ matrix.image-name || '' }}
|
||||||
|
|
||||||
- name: "Assert: compose version is used"
|
- name: ${{ matrix.assertion-name }}
|
||||||
run: |
|
if: ${{ matrix.assertion }}
|
||||||
CURRENT_DOCKER_COMPOSE_VERSION=$(docker compose version --short)
|
run: ${{ matrix.assertion }}
|
||||||
echo "Current docker compose version: $CURRENT_DOCKER_COMPOSE_VERSION"
|
env:
|
||||||
|
IMAGE_NAME: ${{ matrix.image-name || '' }}
|
||||||
if [ "$CURRENT_DOCKER_COMPOSE_VERSION" != "$DOCKER_COMPOSE_VERSION" ]; then
|
|
||||||
echo "Docker compose version is not in $DOCKER_COMPOSE_VERSION version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
test-action-with-docker-context:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test with docker context
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
||||||
|
|
||||||
- name: Set up Docker
|
|
||||||
uses: docker/setup-docker-action@b60f85385d03ac8acfca6d9996982511d8620a19 # v4.3.0
|
|
||||||
with:
|
|
||||||
context: test-context
|
|
||||||
|
|
||||||
- name: Act
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
docker-flags: "--context test-context"
|
|
||||||
compose-file: "./test/docker-compose.yml"
|
|
||||||
compose-version: "latest"
|
|
||||||
|
|||||||
25
.github/workflows/__check-dist.yml
vendored
25
.github/workflows/__check-dist.yml
vendored
@ -3,20 +3,25 @@ name: Internal - Checks for dist
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-dist:
|
check-dist:
|
||||||
name: Check dist
|
name: Check dist
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
- uses: hoverkraft-tech/ci-github-nodejs/actions/setup-node@4b87508052fc8b08a44a5d2d7d5f0636deb6ea3e # 0.15.0
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- id: setup-node
|
||||||
|
uses: hoverkraft-tech/ci-github-nodejs/actions/setup-node@c9d9d041ba4ef35695ee469c4782fa6a8bbebbcc # 0.21.2
|
||||||
|
|
||||||
- name: Build dist/ Directory
|
- name: Build dist/ Directory
|
||||||
id: package
|
id: package
|
||||||
run: npm run package
|
run: ${{ steps.setup-node.outputs.run-script-command }} package
|
||||||
|
|
||||||
# This will fail the workflow if the PR wasn't created by Dependabot.
|
# This will fail the workflow if the PR wasn't created by Dependabot.
|
||||||
- name: Compare Directories
|
- name: Compare Directories
|
||||||
@ -27,13 +32,3 @@ jobs:
|
|||||||
git diff --ignore-space-at-eol --text dist/
|
git diff --ignore-space-at-eol --text dist/
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If `dist/` was different than expected, and this was not a Dependabot
|
|
||||||
# PR, upload the expected version as a workflow artifact.
|
|
||||||
- if: ${{ failure() && steps.diff.outcome == 'failure' }}
|
|
||||||
name: Upload Artifact
|
|
||||||
id: upload
|
|
||||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
|
||||||
with:
|
|
||||||
name: dist
|
|
||||||
path: dist/
|
|
||||||
|
|||||||
15
.github/workflows/__check-nodejs.yml
vendored
15
.github/workflows/__check-nodejs.yml
vendored
@ -3,17 +3,18 @@ name: Internal - Checks for nodejs
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: read
|
|
||||||
security-events: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-nodejs:
|
test-nodejs:
|
||||||
uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@4b87508052fc8b08a44a5d2d7d5f0636deb6ea3e # 0.15.0
|
uses: hoverkraft-tech/ci-github-nodejs/.github/workflows/continuous-integration.yml@c9d9d041ba4ef35695ee469c4782fa6a8bbebbcc # 0.21.2
|
||||||
permissions:
|
permissions:
|
||||||
id-token: write
|
|
||||||
security-events: write
|
|
||||||
contents: read
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
packages: read
|
||||||
|
pull-requests: write
|
||||||
|
security-events: write
|
||||||
with:
|
with:
|
||||||
build: ""
|
build: ""
|
||||||
|
test: |
|
||||||
|
{"coverage":"codecov"}
|
||||||
|
|||||||
25
.github/workflows/__shared-ci.yml
vendored
25
.github/workflows/__shared-ci.yml
vendored
@ -3,17 +3,16 @@ name: Common Continuous Integration tasks
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
packages: read
|
|
||||||
security-events: write
|
|
||||||
statuses: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
linter:
|
linter:
|
||||||
uses: hoverkraft-tech/ci-github-common/.github/workflows/linter.yml@1c379f7f6e0fc850fe5a7111f74d54e159b4dcd2 # 0.26.0
|
uses: hoverkraft-tech/ci-github-common/.github/workflows/linter.yml@b17226e57c8ef31f860719766656ebb6df017218 # 0.31.6
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
statuses: write
|
||||||
with:
|
with:
|
||||||
linter-env: |
|
linter-env: |
|
||||||
FILTER_REGEX_EXCLUDE=dist/**/*
|
FILTER_REGEX_EXCLUDE=dist/**/*
|
||||||
@ -28,14 +27,24 @@ jobs:
|
|||||||
name: Test nodejs
|
name: Test nodejs
|
||||||
needs: linter
|
needs: linter
|
||||||
uses: ./.github/workflows/__check-nodejs.yml
|
uses: ./.github/workflows/__check-nodejs.yml
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
packages: read
|
||||||
|
pull-requests: write
|
||||||
|
security-events: write
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
check-dist:
|
check-dist:
|
||||||
name: Test nodejs
|
name: Test nodejs
|
||||||
needs: linter
|
needs: linter
|
||||||
uses: ./.github/workflows/__check-dist.yml
|
uses: ./.github/workflows/__check-dist.yml
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
check-action:
|
check-action:
|
||||||
name: Test action
|
name: Test action
|
||||||
needs: [check-nodejs, check-dist]
|
needs: [check-nodejs, check-dist]
|
||||||
uses: ./.github/workflows/__check-action.yml
|
uses: ./.github/workflows/__check-action.yml
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|||||||
11
.github/workflows/greetings.yml
vendored
11
.github/workflows/greetings.yml
vendored
@ -6,11 +6,12 @@ on:
|
|||||||
pull_request_target:
|
pull_request_target:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: read
|
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
greetings:
|
greetings:
|
||||||
uses: hoverkraft-tech/ci-github-common/.github/workflows/greetings.yml@1c379f7f6e0fc850fe5a7111f74d54e159b4dcd2 # 0.26.0
|
uses: hoverkraft-tech/ci-github-common/.github/workflows/greetings.yml@b17226e57c8ef31f860719766656ebb6df017218 # 0.31.6
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|||||||
62
.github/workflows/main-ci.yml
vendored
62
.github/workflows/main-ci.yml
vendored
@ -10,43 +10,59 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: "25 8 * * 1"
|
- cron: "25 8 * * 1"
|
||||||
|
|
||||||
permissions:
|
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
packages: read
|
|
||||||
security-events: write
|
|
||||||
statuses: write
|
|
||||||
# FIXME: This is a workaround for having workflow ref. See https://github.com/orgs/community/discussions/38659
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
uses: ./.github/workflows/__shared-ci.yml
|
uses: ./.github/workflows/__shared-ci.yml
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
packages: read
|
||||||
|
pull-requests: write
|
||||||
|
security-events: write
|
||||||
|
statuses: write
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|
||||||
release:
|
prepare-docs:
|
||||||
needs: ci
|
needs: ci
|
||||||
if: github.event_name != 'schedule'
|
if: github.event_name != 'schedule'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
outputs:
|
||||||
|
artifact-id: ${{ steps.upload-artifact.outputs.artifact-id }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: 📖 Generate documentation
|
- name: 📖 Generate documentation
|
||||||
|
id: generate-documentation
|
||||||
uses: hoverkraft-tech/ci-dokumentor@c46a1a108957237cf485103a80b060c35c7dba33 # 0.2.2
|
uses: hoverkraft-tech/ci-dokumentor@c46a1a108957237cf485103a80b060c35c7dba33 # 0.2.2
|
||||||
with:
|
with:
|
||||||
source: action.yml
|
source: action.yml
|
||||||
|
extra-badges: |
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"label":"codecov",
|
||||||
|
"url":"https://codecov.io/gh/hoverkraft-tech/compose-action/graph/badge.svg?token=90JXB7EIMA",
|
||||||
|
"linkUrl":"https://codecov.io/gh/hoverkraft-tech/compose-action"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
- uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
- uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
||||||
id: generate-token
|
id: generate-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ vars.CI_BOT_APP_ID }}
|
app-id: ${{ vars.CI_BOT_APP_ID }}
|
||||||
private-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
- uses: hoverkraft-tech/ci-github-common/actions/create-and-merge-pull-request@1c379f7f6e0fc850fe5a7111f74d54e159b4dcd2 # 0.26.0
|
- uses: hoverkraft-tech/ci-github-common/actions/create-and-merge-pull-request@b17226e57c8ef31f860719766656ebb6df017218 # 0.31.6
|
||||||
with:
|
with:
|
||||||
github-token: ${{ steps.generate-token.outputs.token }}
|
github-token: ${{ steps.generate-token.outputs.token }}
|
||||||
branch: docs/actions-workflows-documentation-update
|
branch: docs/actions-workflows-documentation-update
|
||||||
@ -56,3 +72,23 @@ jobs:
|
|||||||
docs: update actions and workflows documentation
|
docs: update actions and workflows documentation
|
||||||
|
|
||||||
[skip ci]
|
[skip ci]
|
||||||
|
|
||||||
|
- id: upload-artifact
|
||||||
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||||
|
with:
|
||||||
|
name: documentation-files-${{ github.run_id }}
|
||||||
|
path: |
|
||||||
|
${{ steps.generate-documentation.outputs.destination }}
|
||||||
|
.github/logo.svg
|
||||||
|
|
||||||
|
sync-docs:
|
||||||
|
needs: prepare-docs
|
||||||
|
if: needs.prepare-docs.outputs.artifact-id
|
||||||
|
uses: hoverkraft-tech/public-docs/.github/workflows/sync-docs-dispatcher.yml@c40c17f7d6a8090950b3ef4bfc70502707a6bb9f # 0.3.0
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
with:
|
||||||
|
artifact-id: ${{ needs.prepare-docs.outputs.artifact-id }}
|
||||||
|
github-app-id: ${{ vars.CI_BOT_APP_ID }}
|
||||||
|
secrets:
|
||||||
|
github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
|
||||||
|
|||||||
9
.github/workflows/need-fix-to-issue.yml
vendored
9
.github/workflows/need-fix-to-issue.yml
vendored
@ -15,13 +15,14 @@ on:
|
|||||||
before it; to go back further, enter an earlier SHA here"
|
before it; to go back further, enter an earlier SHA here"
|
||||||
required: false
|
required: false
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: read
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
uses: hoverkraft-tech/ci-github-common/.github/workflows/need-fix-to-issue.yml@1c379f7f6e0fc850fe5a7111f74d54e159b4dcd2 # 0.26.0
|
uses: hoverkraft-tech/ci-github-common/.github/workflows/need-fix-to-issue.yml@b17226e57c8ef31f860719766656ebb6df017218 # 0.31.6
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
with:
|
with:
|
||||||
manual-commit-ref: ${{ inputs.manual-commit-ref }}
|
manual-commit-ref: ${{ inputs.manual-commit-ref }}
|
||||||
manual-base-ref: ${{ inputs.manual-base-ref }}
|
manual-base-ref: ${{ inputs.manual-base-ref }}
|
||||||
|
|||||||
26
.github/workflows/prepare-release.yml
vendored
Normal file
26
.github/workflows/prepare-release.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
name: "Prepare release"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
types: [opened, reopened, synchronize]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
uses: hoverkraft-tech/ci-github-publish/.github/workflows/prepare-release.yml@84e8ace407055e7a40ba6670a8c697e1ce2dfafa # 0.20.1
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
id-token: write
|
||||||
|
pull-requests: write
|
||||||
|
with:
|
||||||
|
github-app-id: ${{ vars.CI_BOT_APP_ID }}
|
||||||
|
secrets:
|
||||||
|
github-app-key: ${{ secrets.CI_BOT_APP_PRIVATE_KEY }}
|
||||||
16
.github/workflows/pull-request-ci.yml
vendored
16
.github/workflows/pull-request-ci.yml
vendored
@ -5,13 +5,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
actions: read
|
|
||||||
contents: read
|
|
||||||
packages: read
|
|
||||||
statuses: write
|
|
||||||
security-events: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
@ -20,4 +14,12 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
ci:
|
ci:
|
||||||
uses: ./.github/workflows/__shared-ci.yml
|
uses: ./.github/workflows/__shared-ci.yml
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
packages: read
|
||||||
|
pull-requests: write
|
||||||
|
security-events: write
|
||||||
|
statuses: write
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
|
|||||||
@ -13,15 +13,16 @@ on:
|
|||||||
env:
|
env:
|
||||||
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
update_tag:
|
update_tag:
|
||||||
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
environment:
|
environment:
|
||||||
name: releaseNewActionVersion
|
name: releaseNewActionVersion
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
steps:
|
||||||
- name: Update the ${{ env.TAG_NAME }} tag
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
uses: actions/publish-action@23f4c6f12633a2da8f44938b71fde9afec138fb4 # v0.4.0
|
uses: actions/publish-action@23f4c6f12633a2da8f44938b71fde9afec138fb4 # v0.4.0
|
||||||
|
|||||||
9
.github/workflows/semantic-pull-request.yml
vendored
9
.github/workflows/semantic-pull-request.yml
vendored
@ -7,10 +7,11 @@ on:
|
|||||||
- edited
|
- edited
|
||||||
- synchronize
|
- synchronize
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
contents: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
uses: hoverkraft-tech/ci-github-common/.github/workflows/semantic-pull-request.yml@1c379f7f6e0fc850fe5a7111f74d54e159b4dcd2 # 0.26.0
|
uses: hoverkraft-tech/ci-github-common/.github/workflows/semantic-pull-request.yml@b17226e57c8ef31f860719766656ebb6df017218 # 0.31.6
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|||||||
9
.github/workflows/stale.yml
vendored
9
.github/workflows/stale.yml
vendored
@ -4,10 +4,11 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: "30 1 * * *"
|
- cron: "30 1 * * *"
|
||||||
|
|
||||||
permissions:
|
permissions: {}
|
||||||
issues: write
|
|
||||||
pull-requests: write
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
main:
|
main:
|
||||||
uses: hoverkraft-tech/ci-github-common/.github/workflows/stale.yml@1c379f7f6e0fc850fe5a7111f74d54e159b4dcd2 # 0.26.0
|
uses: hoverkraft-tech/ci-github-common/.github/workflows/stale.yml@b17226e57c8ef31f860719766656ebb6df017218 # 0.31.6
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,6 +12,7 @@ lerna-debug.log*
|
|||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
eslint-report.json
|
||||||
|
|
||||||
# Runtime data
|
# Runtime data
|
||||||
pids
|
pids
|
||||||
|
|||||||
80
AGENTS.md
Normal file
80
AGENTS.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# AGENTS.md — agent instructions and operational contract
|
||||||
|
|
||||||
|
This file exists so automated contributors (Copilot agents, bots, scripts) follow the same guardrails as human maintainers when working in `hoverkraft-tech/compose-action`. It summarizes what to read, which commands to run, and what is out of scope for agents.
|
||||||
|
|
||||||
|
## Organization-wide guidelines
|
||||||
|
|
||||||
|
- Always read and obey [hoverkraft-tech/.github/AGENTS.md](https://github.com/hoverkraft-tech/.github/blob/main/AGENTS.md) before touching this repository.
|
||||||
|
- Apply any additional instructions surfaced by the workspace (global Visual Studio Code prompts, repo-specific notices) alongside this contract.
|
||||||
|
|
||||||
|
## Canonical docs
|
||||||
|
|
||||||
|
- [README.md](./README.md) — product overview, supported inputs, and workflow examples. This is the primary contract for action users.
|
||||||
|
- [CONTRIBUTING.md](./CONTRIBUTING.md) — PR expectations, release hygiene, and how to collaborate with maintainers.
|
||||||
|
- [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) — behavioral expectations for every interaction.
|
||||||
|
|
||||||
|
## Instructional docs
|
||||||
|
|
||||||
|
- Source of truth for runtime logic lives under [`src/`](./src). Tests mirror the same structure under [`src/**/*.test.ts`](./src).
|
||||||
|
- GitHub Action fixtures and sample compose files live under [`test/`](./test). Use them when reproducing CI flows locally.
|
||||||
|
- Build artifacts belong in `dist/`. Never edit generated files by hand; instead update the matching TypeScript source and rerun the packaging commands described below.
|
||||||
|
|
||||||
|
## High-level rules (mandatory)
|
||||||
|
|
||||||
|
- Favor small, reviewable diffs. Coordinate large refactors with maintainers before starting.
|
||||||
|
- Keep behavior changes documented: update `README.md` and any affected workflow snippets.
|
||||||
|
- Never hardcode secrets, tokens, or personal data. Use GitHub Actions secrets or ask maintainers to provision them.
|
||||||
|
- Node 20+ is required. Match the tooling versions declared in `package.json`.
|
||||||
|
|
||||||
|
## Agent operational contract (when modifying code)
|
||||||
|
|
||||||
|
Before opening a PR or pushing a branch:
|
||||||
|
|
||||||
|
1. Read the relevant sections of `README.md` and inspect any affected files in `src/` and `test/`.
|
||||||
|
2. Implement changes in TypeScript source only; regenerate bundles with `npm run package` when shipping executable artifacts.
|
||||||
|
3. Run local validation limited to impacted areas at minimum:
|
||||||
|
- `npm run lint` (or `npm run lint:ci` when you need JSON output for CI).
|
||||||
|
- `npm run build` (type-check only).
|
||||||
|
- `npm run test` for quick feedback; `npm run test:ci` to reproduce CI (coverage + serial runs).
|
||||||
|
4. For action behavior changes, exercise the representative workflow under `test/` (e.g., `test/docker-compose.yml`) to confirm compose invocations behave as expected.
|
||||||
|
5. Add or update unit tests alongside any new logic, covering at least the happy path plus one failure or edge scenario.
|
||||||
|
6. Keep commits self-contained and use conventional commit messages compatible with `@commitlint/config-conventional`.
|
||||||
|
|
||||||
|
When opening a PR:
|
||||||
|
|
||||||
|
- Target a feature branch off `main`.
|
||||||
|
- Describe intent, touched areas, and the manual + automated test plan.
|
||||||
|
- Reference the docs you followed (for example: "Validated against readme > Usage" or "Followed CONTRIBUTING.md".).
|
||||||
|
- Ensure CI (lint, build, tests, package) is green before requesting human review.
|
||||||
|
|
||||||
|
## Validation & quality gates
|
||||||
|
|
||||||
|
- **Build:** `npm run build` must succeed (TypeScript compile cleanly, no `tsc` errors).
|
||||||
|
- **Lint:** `npm run lint:ci` must pass with no new warnings. Attach `eslint-report.json` to CI artifacts when relevant.
|
||||||
|
- **Tests:** `npm run test:ci` must pass and update coverage artifacts (see `coverage/`).
|
||||||
|
- **Bundle:** `npm run package` must regenerate `dist/` outputs; include updated bundles in the PR if runtime code changed.
|
||||||
|
|
||||||
|
## Allowed agent actions (examples)
|
||||||
|
|
||||||
|
- Fix documentation, typos, or metadata referenced by the GitHub Marketplace listing.
|
||||||
|
- Add or update unit tests, mocks, and fixtures in `src/` or `test/`.
|
||||||
|
- Refactor TypeScript modules in small, behavior-preserving increments (with tests and package outputs refreshed).
|
||||||
|
- Adjust CI/workflow helpers under `test/` to improve local reproducibility.
|
||||||
|
|
||||||
|
## Disallowed actions (must not do)
|
||||||
|
|
||||||
|
- Do not commit generated `dist/` artifacts without updating the corresponding TypeScript source and documenting the command used.
|
||||||
|
- Do not introduce new runtime dependencies without maintainer approval; prefer built-in Node APIs or existing deps.
|
||||||
|
- Do not modify Dockerfiles or GitHub Actions workflows to add secrets, credentials, or privileged steps.
|
||||||
|
- Do not land breaking changes to the public action inputs/outputs without updating `README.md` and gaining explicit maintainer sign-off.
|
||||||
|
|
||||||
|
## Guidance summary (quick checklist)
|
||||||
|
|
||||||
|
1. Read `README.md` + relevant source/test files.
|
||||||
|
2. Make the minimal change; add tests.
|
||||||
|
3. Run `npm run lint`, `npm run build`, `npm run test:ci`, and `npm run package`.
|
||||||
|
4. Open a PR referencing the docs you followed and include the test plan.
|
||||||
|
|
||||||
|
## If uncertain
|
||||||
|
|
||||||
|
Open an issue or draft PR in this repository describing the scenario, what docs you read, and the question you still have. Ping maintainers instead of guessing. When in doubt about the workflow contract, defer to the `README.md` and organization-wide AGENTS file.
|
||||||
3
Makefile
3
Makefile
@ -13,7 +13,8 @@ lint-fix: ## Execute linting and fix
|
|||||||
-e FIX_YAML_PRETTIER=true \
|
-e FIX_YAML_PRETTIER=true \
|
||||||
-e FIX_MARKDOWN=true \
|
-e FIX_MARKDOWN=true \
|
||||||
-e FIX_MARKDOWN_PRETTIER=true \
|
-e FIX_MARKDOWN_PRETTIER=true \
|
||||||
-e FIX_NATURAL_LANGUAGE=true)
|
-e FIX_NATURAL_LANGUAGE=true \
|
||||||
|
)
|
||||||
|
|
||||||
ci: ## Execute all formats and checks
|
ci: ## Execute all formats and checks
|
||||||
@npm install
|
@npm install
|
||||||
|
|||||||
15
README.md
15
README.md
@ -17,6 +17,7 @@
|
|||||||
[](http://choosealicense.com/licenses/mit/)
|
[](http://choosealicense.com/licenses/mit/)
|
||||||
[](https://img.shields.io/github/stars/hoverkraft-tech/compose-action?style=social)
|
[](https://img.shields.io/github/stars/hoverkraft-tech/compose-action?style=social)
|
||||||
[](https://github.com/hoverkraft-tech/compose-action/blob/main/CONTRIBUTING.md)
|
[](https://github.com/hoverkraft-tech/compose-action/blob/main/CONTRIBUTING.md)
|
||||||
|
[](https://codecov.io/gh/hoverkraft-tech/compose-action)
|
||||||
|
|
||||||
<!-- badges:end -->
|
<!-- badges:end -->
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ Some extra options can be passed to the `docker compose down` command using the
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0
|
- uses: hoverkraft-tech/compose-action@248470ecc5ed40d8ed3d4480d8260d77179ef579 # v2.4.2
|
||||||
with:
|
with:
|
||||||
# Additional options to pass to `docker` command.
|
# Additional options to pass to `docker` command.
|
||||||
docker-flags: ""
|
docker-flags: ""
|
||||||
@ -138,7 +139,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4.2.2
|
- uses: actions/checkout@v4.2.2
|
||||||
|
|
||||||
- name: Run docker compose
|
- name: Run docker compose
|
||||||
uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0
|
uses: hoverkraft-tech/compose-action@248470ecc5ed40d8ed3d4480d8260d77179ef579 # v2.4.2
|
||||||
with:
|
with:
|
||||||
compose-file: "./docker/docker-compose.yml"
|
compose-file: "./docker/docker-compose.yml"
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ jobs:
|
|||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.2.2
|
- uses: actions/checkout@v4.2.2
|
||||||
- uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0
|
- uses: hoverkraft-tech/compose-action@248470ecc5ed40d8ed3d4480d8260d77179ef579 # v2.4.2
|
||||||
with:
|
with:
|
||||||
compose-file: "./docker/docker-compose.yml"
|
compose-file: "./docker/docker-compose.yml"
|
||||||
env:
|
env:
|
||||||
@ -167,7 +168,7 @@ Perform `docker compose up` to some given service instead of all of them
|
|||||||
steps:
|
steps:
|
||||||
# need checkout before using compose-action
|
# need checkout before using compose-action
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0
|
- uses: hoverkraft-tech/compose-action@248470ecc5ed40d8ed3d4480d8260d77179ef579 # v2.4.2
|
||||||
with:
|
with:
|
||||||
compose-file: "./docker/docker-compose.yml"
|
compose-file: "./docker/docker-compose.yml"
|
||||||
services: |
|
services: |
|
||||||
@ -205,7 +206,7 @@ A full list of flags can be found in the [Docker compose documentation](https://
|
|||||||
steps:
|
steps:
|
||||||
# need checkout before using compose-action
|
# need checkout before using compose-action
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0
|
- uses: hoverkraft-tech/compose-action@248470ecc5ed40d8ed3d4480d8260d77179ef579 # v2.4.2
|
||||||
with:
|
with:
|
||||||
compose-file: "./docker/docker-compose.yml"
|
compose-file: "./docker/docker-compose.yml"
|
||||||
compose-flags: "--profile profile-1"
|
compose-flags: "--profile profile-1"
|
||||||
@ -219,7 +220,7 @@ This is useful when you have a base compose file and additional files for differ
|
|||||||
steps:
|
steps:
|
||||||
# need checkout before using compose-action
|
# need checkout before using compose-action
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: hoverkraft-tech/compose-action@b716db5b717cb9b81e391fe638e5aceaa2299e43 # v2.4.0
|
- uses: hoverkraft-tech/compose-action@248470ecc5ed40d8ed3d4480d8260d77179ef579 # v2.4.2
|
||||||
with:
|
with:
|
||||||
compose-file: |
|
compose-file: |
|
||||||
./docker/docker-compose.yml
|
./docker/docker-compose.yml
|
||||||
@ -247,7 +248,7 @@ This project is licensed under the MIT License.
|
|||||||
|
|
||||||
SPDX-License-Identifier: MIT
|
SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
Copyright © 2025 hoverkraft
|
Copyright © 2026 hoverkraft
|
||||||
|
|
||||||
For more details, see the [license](http://choosealicense.com/licenses/mit/).
|
For more details, see the [license](http://choosealicense.com/licenses/mit/).
|
||||||
|
|
||||||
|
|||||||
3670
dist/index.js
generated
vendored
3670
dist/index.js
generated
vendored
File diff suppressed because it is too large
Load Diff
729
dist/post.js
generated
vendored
729
dist/post.js
generated
vendored
File diff suppressed because it is too large
Load Diff
3
eslint.config.mjs
Normal file
3
eslint.config.mjs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { default as tsDevToolsCore } from "@ts-dev-tools/core/dist/eslint-plugin-ts-dev-tools/index.js";
|
||||||
|
|
||||||
|
export default tsDevToolsCore.default;
|
||||||
524
package-lock.json
generated
524
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
55
package.json
55
package.json
@ -24,14 +24,14 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.11.1",
|
"@actions/core": "^2.0.1",
|
||||||
"@actions/github": "^6.0.1",
|
"@actions/github": "^6.0.1",
|
||||||
"@actions/tool-cache": "^2.0.2",
|
"@actions/tool-cache": "^2.0.2",
|
||||||
"@octokit/action": "^8.0.2",
|
"@octokit/action": "^8.0.4",
|
||||||
"docker-compose": "^1.3.0"
|
"docker-compose": "^1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ts-dev-tools/core": "^1.9.7",
|
"@ts-dev-tools/core": "^1.9.14",
|
||||||
"@vercel/ncc": "^0.38.4",
|
"@vercel/ncc": "^0.38.4",
|
||||||
"eslint-plugin-github": "^6.0.0",
|
"eslint-plugin-github": "^6.0.0",
|
||||||
"eslint-plugin-jsonc": "^2.21.0"
|
"eslint-plugin-jsonc": "^2.21.0"
|
||||||
@ -42,14 +42,15 @@
|
|||||||
"package:post": "ncc build src/post.ts -o dist/post && mv dist/post/index.js dist/post.js && rm -rf dist/post",
|
"package:post": "ncc build src/post.ts -o dist/post && mv dist/post/index.js dist/post.js && rm -rf dist/post",
|
||||||
"package:watch": "npm run package -- --watch",
|
"package:watch": "npm run package -- --watch",
|
||||||
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
"lint": "eslint \"src/**/*.{ts,tsx}\"",
|
||||||
"all": "npm run format && npm run lint && npm run test && npm run package",
|
"lint:ci": "npm run lint -- --output-file eslint-report.json --format json",
|
||||||
|
"all": "npm run format && npm run lint:ci && npm run test:ci && npm run package",
|
||||||
"build": "tsc --noEmit",
|
"build": "tsc --noEmit",
|
||||||
"format": "prettier --cache --write .",
|
"format": "prettier --cache --write .",
|
||||||
"jest": "jest --detectOpenHandles --forceExit",
|
"jest": "jest --detectOpenHandles --forceExit",
|
||||||
"test": "npm run jest --maxWorkers=50%",
|
"test": "npm run jest -- --maxWorkers=50%",
|
||||||
"test:watch": "npm run jest --watch --maxWorkers=25%",
|
"test:watch": "npm run jest --watch -- --maxWorkers=25%",
|
||||||
"test:cov": "npm run test --coverage",
|
"test:cov": "npm run test -- --coverage",
|
||||||
"test:ci": "npm run test:cov --runInBand",
|
"test:ci": "npm run jest -- --coverage --runInBand",
|
||||||
"prepare": "ts-dev-tools install"
|
"prepare": "ts-dev-tools install"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
@ -84,43 +85,11 @@
|
|||||||
"**/src/**/*.[jt]s?(x)"
|
"**/src/**/*.[jt]s?(x)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
|
||||||
"root": true,
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"plugins": [
|
|
||||||
"@typescript-eslint",
|
|
||||||
"jest"
|
|
||||||
],
|
|
||||||
"extends": [
|
|
||||||
"eslint:recommended",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"plugin:jest/recommended",
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"es2021": true
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaFeatures": {
|
|
||||||
"jsx": true
|
|
||||||
},
|
|
||||||
"ecmaVersion": 12,
|
|
||||||
"sourceType": "module"
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"jest": {
|
|
||||||
"version": "detect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ignorePatterns": [
|
|
||||||
"dist",
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
"trailingComma": "es5"
|
"trailingComma": "es5",
|
||||||
|
"plugins": []
|
||||||
},
|
},
|
||||||
"commitlint": {
|
"commitlint": {
|
||||||
"extends": [
|
"extends": [
|
||||||
@ -139,6 +108,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tsDevTools": {
|
"tsDevTools": {
|
||||||
"version": "20220617100200-prettier-cache"
|
"version": "20250623095600-remove-prettier-oxc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -112,6 +112,130 @@ describe("DockerComposeService", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should throw formatted error when upAll fails with docker-compose result", async () => {
|
||||||
|
const upInputs: UpInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: ["docker-compose.yml"],
|
||||||
|
services: [],
|
||||||
|
composeFlags: [],
|
||||||
|
upFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const dockerComposeError = {
|
||||||
|
exitCode: 1,
|
||||||
|
err: "Error: unable to pull image\nfailed to resolve reference",
|
||||||
|
out: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
upAllMock.mockRejectedValue(dockerComposeError);
|
||||||
|
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow(
|
||||||
|
"Docker Compose command failed with exit code 1"
|
||||||
|
);
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow("unable to pull image");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw formatted error when upMany fails with docker-compose result", async () => {
|
||||||
|
const upInputs: UpInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: ["docker-compose.yml"],
|
||||||
|
services: ["web"],
|
||||||
|
composeFlags: [],
|
||||||
|
upFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const dockerComposeError = {
|
||||||
|
exitCode: 1,
|
||||||
|
err: "Service 'web' failed to start",
|
||||||
|
out: "Starting web...",
|
||||||
|
};
|
||||||
|
|
||||||
|
upManyMock.mockRejectedValue(dockerComposeError);
|
||||||
|
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow(
|
||||||
|
"Docker Compose command failed with exit code 1"
|
||||||
|
);
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow("Service 'web' failed to start");
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow("Starting web...");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should pass through docker-compose result without exit code", async () => {
|
||||||
|
const upInputs: UpInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: ["docker-compose.yml"],
|
||||||
|
services: [],
|
||||||
|
composeFlags: [],
|
||||||
|
upFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const dockerComposeError = {
|
||||||
|
exitCode: null,
|
||||||
|
err: "Some error without exit code",
|
||||||
|
out: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
upAllMock.mockRejectedValue(dockerComposeError);
|
||||||
|
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow("Some error without exit code");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should pass through standard Error objects", async () => {
|
||||||
|
const upInputs: UpInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: ["docker-compose.yml"],
|
||||||
|
services: [],
|
||||||
|
composeFlags: [],
|
||||||
|
upFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const standardError = new Error("Standard error message");
|
||||||
|
upAllMock.mockRejectedValue(standardError);
|
||||||
|
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow("Standard error message");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should pass through error strings", async () => {
|
||||||
|
const upInputs: UpInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: ["docker-compose.yml"],
|
||||||
|
services: [],
|
||||||
|
composeFlags: [],
|
||||||
|
upFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const unknownError = "Some unknown error";
|
||||||
|
upAllMock.mockRejectedValue(unknownError);
|
||||||
|
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow("Some unknown error");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle unknown error types gracefully", async () => {
|
||||||
|
const upInputs: UpInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: ["docker-compose.yml"],
|
||||||
|
services: [],
|
||||||
|
composeFlags: [],
|
||||||
|
upFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const unknownError = { unexpected: "error format" };
|
||||||
|
upAllMock.mockRejectedValue(unknownError);
|
||||||
|
|
||||||
|
await expect(service.up(upInputs)).rejects.toThrow(JSON.stringify(unknownError));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("down", () => {
|
describe("down", () => {
|
||||||
@ -139,6 +263,30 @@ describe("DockerComposeService", () => {
|
|||||||
callback: expect.any(Function),
|
callback: expect.any(Function),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should throw formatted error when down fails with docker-compose result", async () => {
|
||||||
|
const downInputs: DownInputs = {
|
||||||
|
dockerFlags: [],
|
||||||
|
composeFiles: [],
|
||||||
|
composeFlags: [],
|
||||||
|
downFlags: [],
|
||||||
|
cwd: "/current/working/dir",
|
||||||
|
serviceLogger: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const dockerComposeError = {
|
||||||
|
exitCode: 1,
|
||||||
|
err: "Error stopping containers",
|
||||||
|
out: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
downMock.mockRejectedValue(dockerComposeError);
|
||||||
|
|
||||||
|
await expect(service.down(downInputs)).rejects.toThrow(
|
||||||
|
"Docker Compose command failed with exit code 1"
|
||||||
|
);
|
||||||
|
await expect(service.down(downInputs)).rejects.toThrow("Error stopping containers");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("logs", () => {
|
describe("logs", () => {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import {
|
|||||||
down,
|
down,
|
||||||
IDockerComposeLogOptions,
|
IDockerComposeLogOptions,
|
||||||
IDockerComposeOptions,
|
IDockerComposeOptions,
|
||||||
|
IDockerComposeResult,
|
||||||
logs,
|
logs,
|
||||||
upAll,
|
upAll,
|
||||||
upMany,
|
upMany,
|
||||||
@ -27,12 +28,16 @@ export class DockerComposeService {
|
|||||||
commandOptions: upFlags,
|
commandOptions: upFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (services.length > 0) {
|
try {
|
||||||
await upMany(services, options);
|
if (services.length > 0) {
|
||||||
return;
|
await upMany(services, options);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await upAll(options);
|
await upAll(options);
|
||||||
|
} catch (error) {
|
||||||
|
throw this.formatDockerComposeError(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async down({ downFlags, ...optionsInputs }: DownInputs): Promise<void> {
|
async down({ downFlags, ...optionsInputs }: DownInputs): Promise<void> {
|
||||||
@ -41,7 +46,11 @@ export class DockerComposeService {
|
|||||||
commandOptions: downFlags,
|
commandOptions: downFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
await down(options);
|
try {
|
||||||
|
await down(options);
|
||||||
|
} catch (error) {
|
||||||
|
throw this.formatDockerComposeError(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async logs({ services, ...optionsInputs }: LogsInputs): Promise<{
|
async logs({ services, ...optionsInputs }: LogsInputs): Promise<{
|
||||||
@ -79,4 +88,61 @@ export class DockerComposeService {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats docker-compose errors into proper Error objects with readable messages
|
||||||
|
*/
|
||||||
|
private formatDockerComposeError(error: unknown): Error {
|
||||||
|
// If it's already an Error, return it
|
||||||
|
if (error instanceof Error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle docker-compose result objects
|
||||||
|
if (this.isDockerComposeResult(error)) {
|
||||||
|
const parts: string[] = [];
|
||||||
|
|
||||||
|
// Add exit code information
|
||||||
|
if (error.exitCode !== null) {
|
||||||
|
parts.push(`Docker Compose command failed with exit code ${error.exitCode}`);
|
||||||
|
} else {
|
||||||
|
parts.push("Docker Compose command failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add error stream output if available
|
||||||
|
if (error.err && error.err.trim()) {
|
||||||
|
parts.push("\nError output:");
|
||||||
|
parts.push(error.err.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add standard output if available and different from error output
|
||||||
|
if (error.out && error.out.trim() && error.out !== error.err) {
|
||||||
|
parts.push("\nStandard output:");
|
||||||
|
parts.push(error.out.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Error(parts.join("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle string errors
|
||||||
|
if (typeof error === "string") {
|
||||||
|
return new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback for unknown error types
|
||||||
|
return new Error(JSON.stringify(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type guard to check if an object is a docker-compose result
|
||||||
|
*/
|
||||||
|
private isDockerComposeResult(error: unknown): error is IDockerComposeResult {
|
||||||
|
return (
|
||||||
|
typeof error === "object" &&
|
||||||
|
error !== null &&
|
||||||
|
"exitCode" in error &&
|
||||||
|
"err" in error &&
|
||||||
|
"out" in error
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user