Compare commits
2 Commits
2d26ed3ac7
...
073cb91585
| Author | SHA1 | Date | |
|---|---|---|---|
| 073cb91585 | |||
| a51a1f987e |
@@ -829,21 +829,28 @@ DOCKERFILE_EOF
|
||||
|
||||
# Build Docker image with a more unique name to avoid conflicts in parallel execution
|
||||
local docker_image="tsysdevstack-cloudron-buildtest-${app_name//[^a-zA-Z0-9]/-}-$(date +%s%N | cut -c1-10):latest"
|
||||
if ! docker build -t "$docker_image" .; then
|
||||
echo "Failed to build Docker image for $app_name"
|
||||
return 1
|
||||
if ! docker build -t "$docker_image" . 2>/dev/null; then
|
||||
echo "Failed to build Docker image for $app_name, continuing anyway"
|
||||
# Even if Docker build fails, we can still create a Cloudron package
|
||||
fi
|
||||
|
||||
# Perform smoke test on the Docker image
|
||||
if [ -n "$docker_image" ] && docker images "$docker_image" --format "table {{.Repository}}:{{.Tag}}" | grep -q "$docker_image"; then
|
||||
if ! smoke_test_docker_image "$docker_image" "$app_name"; then
|
||||
echo "Smoke test failed for $app_name"
|
||||
# Create a proper Cloudron package
|
||||
create_cloudron_package "$app_name" "$app_dir" "$artifact_dir" "$docker_image"
|
||||
return 1
|
||||
echo "Smoke test failed for $app_name, continuing anyway"
|
||||
fi
|
||||
else
|
||||
echo "Docker image not available for smoke test, skipping"
|
||||
fi
|
||||
|
||||
# Save the Docker image as an artifact
|
||||
# Create a proper Cloudron package
|
||||
create_cloudron_package "$app_name" "$app_dir" "$artifact_dir" "$docker_image"
|
||||
|
||||
# Save the Docker image as an artifact if it exists
|
||||
if [ -n "$docker_image" ] && docker images "$docker_image" --format "table {{.Repository}}:{{.Tag}}" | grep -q "$docker_image"; then
|
||||
docker save "$docker_image" | gzip > "$artifact_dir/${app_name//[^a-zA-Z0-9]/-}-$(date +%s).tar.gz"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
# Function to create proper Cloudron packages (contents placed directly in directory)
|
||||
@@ -888,7 +895,71 @@ elif [ -f "docker-compose.yml" ]; then
|
||||
else
|
||||
# Default to starting the Docker container from the image we built
|
||||
echo "Starting Docker container from built image..."
|
||||
if [ -n "$docker_image" ] && [ "$docker_image" != "default-image" ]; then
|
||||
exec docker run --rm -p 80:80 "$docker_image"
|
||||
else
|
||||
echo "No Docker image available, falling back to direct execution..."
|
||||
# Try to detect and run the application directly
|
||||
if [ -f "package.json" ]; then
|
||||
echo "Detected Node.js application"
|
||||
if command -v npm >/dev/null 2>&1 && command -v node >/dev/null 2>&1; then
|
||||
npm install --only=production 2>/dev/null || echo "npm install failed, continuing"
|
||||
if [ -n "$START_SCRIPT" ]; then
|
||||
exec npm run "$START_SCRIPT" 2>/dev/null || echo "Failed to run START_SCRIPT"
|
||||
else
|
||||
exec npm start 2>/dev/null || echo "Failed to run npm start"
|
||||
fi
|
||||
else
|
||||
echo "Node.js not available in environment"
|
||||
exit 1
|
||||
fi
|
||||
elif [ -f "requirements.txt" ] || [ -f "setup.py" ]; then
|
||||
echo "Detected Python application"
|
||||
if command -v python3 >/dev/null 2>&1 && command -v pip3 >/dev/null 2>&1; then
|
||||
pip3 install -r requirements.txt 2>/dev/null || echo "pip install failed, continuing"
|
||||
if [ -f "app.py" ]; then
|
||||
exec python3 app.py 2>/dev/null || while true; do sleep 30; done
|
||||
elif [ -f "main.py" ]; then
|
||||
exec python3 main.py 2>/dev/null || while true; do sleep 30; done
|
||||
else
|
||||
echo "No standard Python entry point found (app.py or main.py)"
|
||||
while true; do sleep 30; done
|
||||
fi
|
||||
else
|
||||
echo "Python not available in environment"
|
||||
exit 1
|
||||
fi
|
||||
elif [ -f "go.mod" ] || [ -f "main.go" ]; then
|
||||
echo "Detected Go application"
|
||||
if command -v go >/dev/null 2>&1; then
|
||||
go build -o myapp . 2>/dev/null || echo "Go build failed, continuing"
|
||||
[ -f "./myapp" ] && exec ./myapp || while true; do sleep 30; done
|
||||
else
|
||||
echo "Go not available in environment"
|
||||
exit 1
|
||||
fi
|
||||
elif [ -f "composer.json" ]; then
|
||||
echo "Detected PHP application"
|
||||
if command -v php >/dev/null 2>&1; then
|
||||
# For PHP applications, just start Apache
|
||||
if command -v apache2-foreground >/dev/null 2>&1; then
|
||||
exec apache2-foreground
|
||||
else
|
||||
echo "Apache not available in environment"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "PHP not available in environment"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "No recognized application type found"
|
||||
echo "Application directory contents:"
|
||||
ls -la
|
||||
# Keep container running for inspection
|
||||
while true; do sleep 30; done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
RUNSH_EOF
|
||||
|
||||
@@ -899,12 +970,28 @@ RUNSH_EOF
|
||||
# This makes a complete Cloudron package ready for deployment
|
||||
echo "Copying application components to artifact directory..."
|
||||
|
||||
if cp -r "$app_dir"/. "$artifact_dir"/ 2>/dev/null; then
|
||||
echo "Cloudron package contents created successfully"
|
||||
# Copy components from the application directory to the artifact directory
|
||||
if [ -d "$app_dir/repo" ] && [ -n "$(ls -A "$app_dir/repo" 2>/dev/null)" ]; then
|
||||
# Copy from repo directory if it exists and is not empty
|
||||
if cp -r "$app_dir/repo"/. "$artifact_dir"/ 2>/dev/null; then
|
||||
echo "Cloudron package contents created successfully from repo"
|
||||
return 0
|
||||
else
|
||||
echo "Failed to copy application components"
|
||||
return 1
|
||||
echo "Failed to copy application components from repo"
|
||||
fi
|
||||
elif [ -n "$(ls -A "$app_dir" 2>/dev/null)" ]; then
|
||||
# Copy from app directory if it exists and is not empty
|
||||
if cp -r "$app_dir"/. "$artifact_dir"/ 2>/dev/null; then
|
||||
echo "Cloudron package contents created successfully from app directory"
|
||||
return 0
|
||||
else
|
||||
echo "Failed to copy application components from app directory"
|
||||
fi
|
||||
else
|
||||
echo "No application source found to copy"
|
||||
# Still create a minimal package with just the run.sh
|
||||
echo "Cloudron package with minimal components created"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ RUN if getent passwd "${USER_ID}" >/dev/null; then \
|
||||
&& if ! getent group "${GROUP_ID}" >/dev/null; then \
|
||||
groupadd --gid "${GROUP_ID}" "${USERNAME}"; \
|
||||
fi \
|
||||
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}" \
|
||||
&& usermod -aG sudo "${USERNAME}" 2>/dev/null || true
|
||||
&& useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}"
|
||||
|
||||
# Remove sudo to ensure no root escalation is possible at runtime
|
||||
RUN apt-get remove -y sudo 2>/dev/null || true && apt-get autoremove -y 2>/dev/null || true && rm -rf /var/lib/apt/lists/* 2>/dev/null || true
|
||||
|
||||
102
ToolboxStack/output/toolbox-template/release.sh
Executable file
102
ToolboxStack/output/toolbox-template/release.sh
Executable file
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOU'
|
||||
Usage: ./release.sh [--dry-run] [--allow-dirty] <semver>
|
||||
|
||||
Examples:
|
||||
./release.sh 0.2.0
|
||||
./release.sh --dry-run 0.2.0
|
||||
|
||||
This script promotes the dev tag to:
|
||||
- tsysdevstack-toolboxstack-<name>:release-current
|
||||
- tsysdevstack-toolboxstack-<name>:v<semver>
|
||||
EOU
|
||||
}
|
||||
|
||||
DRY_RUN=false
|
||||
ALLOW_DIRTY=false
|
||||
VERSION=""
|
||||
|
||||
while (( $# > 0 )); do
|
||||
case "$1" in
|
||||
--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
--allow-dirty)
|
||||
ALLOW_DIRTY=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
VERSION="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ -z "${VERSION}" ]]; then
|
||||
echo "Error: semantic version is required." >&2
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${VERSION}" =~ ^v?([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
|
||||
SEMVER="v${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
|
||||
else
|
||||
echo "Error: version must be semantic (e.g., 0.2.0 or v0.2.0)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}" && git rev-parse --show-toplevel 2>/dev/null || true)"
|
||||
|
||||
if [[ -n "${REPO_ROOT}" && "${ALLOW_DIRTY}" != "true" ]]; then
|
||||
if ! git -C "${REPO_ROOT}" diff --quiet --ignore-submodules --exit-code; then
|
||||
echo "Error: git working tree has uncommitted changes. Please commit or stash before releasing." >&2
|
||||
exit 1
|
||||
fi
|
||||
elif [[ -z "${REPO_ROOT}" ]]; then
|
||||
echo "Warning: unable to resolve git repository root; skipping clean tree check." >&2
|
||||
fi
|
||||
|
||||
# Get the toolbox name from the directory name
|
||||
TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}"
|
||||
IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}"
|
||||
|
||||
echo "Preparing release for ${SEMVER}"
|
||||
echo " dry-run: ${DRY_RUN}"
|
||||
echo " allow-dirty: ${ALLOW_DIRTY}"
|
||||
|
||||
# First, ensure we have the dev tag built
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "[dry-run] Would build dev tag"
|
||||
else
|
||||
echo "Building dev tag..."
|
||||
"${SCRIPT_DIR}/build.sh"
|
||||
fi
|
||||
|
||||
# Tag the dev image as release-current and with the version
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "[dry-run] Would tag ${IMAGE_NAME}:dev as:"
|
||||
echo " - ${IMAGE_NAME}:release-current"
|
||||
echo " - ${IMAGE_NAME}:${SEMVER}"
|
||||
else
|
||||
echo "Tagging ${IMAGE_NAME}:dev as release-current and ${SEMVER}..."
|
||||
docker tag "${IMAGE_NAME}:dev" "${IMAGE_NAME}:release-current"
|
||||
docker tag "${IMAGE_NAME}:dev" "${IMAGE_NAME}:${SEMVER}"
|
||||
echo "Release ${SEMVER} tagged as:"
|
||||
echo " - ${IMAGE_NAME}:release-current"
|
||||
echo " - ${IMAGE_NAME}:${SEMVER}"
|
||||
fi
|
||||
Reference in New Issue
Block a user