diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index bd344da..6b613e0 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -41,31 +41,104 @@ jobs: PORTAINER_API_KEY: ${{ secrets.PORTAINER_API_KEY }} PORTAINER_ENDPOINT_ID: ${{ secrets.PORTAINER_ENDPOINT_ID }} run: | - STACK_ID=$(curl -sf \ + set -u + + echo "Portainer deploy debug" + echo "PORTAINER_URL=${PORTAINER_URL}" + echo "STACK_NAME=${STACK_NAME}" + echo "PORTAINER_ENDPOINT_ID=${PORTAINER_ENDPOINT_ID}" + + PORTAINER_HOST=$(printf '%s' "${PORTAINER_URL}" | sed -E 's#^[a-zA-Z]+://##; s#/.*$##; s/:.*$//') + echo "Resolved host target: ${PORTAINER_HOST}" + + if command -v getent >/dev/null 2>&1; then + echo "Host lookup (getent):" + getent hosts "${PORTAINER_HOST}" || true + fi + + STACKS_BODY=$(mktemp) + STACKS_ERR=$(mktemp) + + STACKS_HTTP_CODE=$(curl -sS \ + -o "${STACKS_BODY}" \ + -w "%{http_code}" \ "${PORTAINER_URL}/api/stacks" \ -H "X-API-Key: ${PORTAINER_API_KEY}" \ - | jq -r --arg stack_name "$STACK_NAME" '.[] | select(.Name == $stack_name) | .Id' \ - | head -n 1) + 2>"${STACKS_ERR}") + STACKS_CURL_EXIT=$? + + echo "GET /api/stacks curl exit: ${STACKS_CURL_EXIT}" + echo "GET /api/stacks http code: ${STACKS_HTTP_CODE}" + echo "GET /api/stacks stderr:" + cat "${STACKS_ERR}" || true + echo "GET /api/stacks response body:" + cat "${STACKS_BODY}" || true + + if [ "${STACKS_CURL_EXIT}" -ne 0 ]; then + echo "Failed to reach Portainer API while listing stacks." + exit "${STACKS_CURL_EXIT}" + fi + + if [ "${STACKS_HTTP_CODE}" -lt 200 ] || [ "${STACKS_HTTP_CODE}" -ge 300 ]; then + echo "Portainer returned a non-success status for stack listing." + exit 1 + fi + + STACK_ID=$(jq -r --arg stack_name "${STACK_NAME}" '.[] | select(.Name == $stack_name) | .Id' "${STACKS_BODY}" | head -n 1) + + APPLY_BODY=$(mktemp) + APPLY_ERR=$(mktemp) + + if [ -n "${STACK_ID}" ]; then + echo "Existing stack found with id=${STACK_ID}; sending update request" - if [ -n "$STACK_ID" ]; then PAYLOAD=$(jq -n \ --rawfile stack_file docker-compose.prod.yml \ '{StackFileContent: $stack_file, Env: [], Prune: false, PullImage: false}') - curl -sf -X PUT \ + APPLY_HTTP_CODE=$(curl -sS -X PUT \ + -o "${APPLY_BODY}" \ + -w "%{http_code}" \ "${PORTAINER_URL}/api/stacks/${STACK_ID}?endpointId=${PORTAINER_ENDPOINT_ID}" \ -H "X-API-Key: ${PORTAINER_API_KEY}" \ -H "Content-Type: application/json" \ - -d "$PAYLOAD" + -d "${PAYLOAD}" \ + 2>"${APPLY_ERR}") + APPLY_CURL_EXIT=$? else + echo "Stack not found; sending create request" + PAYLOAD=$(jq -n \ - --arg name "$STACK_NAME" \ + --arg name "${STACK_NAME}" \ --rawfile stack_file docker-compose.prod.yml \ '{Name: $name, StackFileContent: $stack_file, Env: [], FromAppTemplate: false}') - curl -sf -X POST \ + APPLY_HTTP_CODE=$(curl -sS -X POST \ + -o "${APPLY_BODY}" \ + -w "%{http_code}" \ "${PORTAINER_URL}/api/stacks/create/standalone/string?endpointId=${PORTAINER_ENDPOINT_ID}" \ -H "X-API-Key: ${PORTAINER_API_KEY}" \ -H "Content-Type: application/json" \ - -d "$PAYLOAD" + -d "${PAYLOAD}" \ + 2>"${APPLY_ERR}") + APPLY_CURL_EXIT=$? fi + + echo "Apply curl exit: ${APPLY_CURL_EXIT}" + echo "Apply http code: ${APPLY_HTTP_CODE}" + echo "Apply stderr:" + cat "${APPLY_ERR}" || true + echo "Apply response body:" + cat "${APPLY_BODY}" || true + + if [ "${APPLY_CURL_EXIT}" -ne 0 ]; then + echo "Failed to reach Portainer API while applying stack changes." + exit "${APPLY_CURL_EXIT}" + fi + + if [ "${APPLY_HTTP_CODE}" -lt 200 ] || [ "${APPLY_HTTP_CODE}" -ge 300 ]; then + echo "Portainer returned a non-success status while applying stack changes." + exit 1 + fi + + echo "Portainer deploy step completed successfully"