feat(toolbox): update toolbox template configuration
- Update ToolboxStack/output/toolbox-template/Dockerfile with latest container settings - Update ToolboxStack/output/toolbox-template/PROMPT with enhanced instructions - Update ToolboxStack/output/toolbox-template/SEED with updated seed data - Update ToolboxStack/output/toolbox-template/aqua.yaml with refined tool management - Update ToolboxStack/output/toolbox-template/build.sh with improved build process - Update ToolboxStack/output/toolbox-template/docker-compose.yml with enhanced service definitions - Update ToolboxStack/output/toolbox-template/release.sh with enhanced release process - Update ToolboxStack/output/toolbox-template/run.sh with improved runtime configuration This enhances the toolbox template for creating new developer environments.
This commit is contained in:
		| @@ -16,6 +16,26 @@ RUN if getent passwd "${USER_ID}" >/dev/null; then \ | |||||||
|     fi \ |     fi \ | ||||||
|     && useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}" |     && useradd --uid "${USER_ID}" --gid "${GROUP_ID}" --shell /usr/bin/zsh --create-home "${USERNAME}" | ||||||
|  |  | ||||||
|  | # Install toolbox-specific packages here | ||||||
|  | # Example: | ||||||
|  | # RUN apt-get update && apt-get install -y --no-install-recommends \ | ||||||
|  | #     specific-package \ | ||||||
|  | #     && apt-get clean \ | ||||||
|  | #     && rm -rf /var/lib/apt/lists/* | ||||||
|  |  | ||||||
|  | # Install toolbox-specific aqua packages here | ||||||
|  | # Example: | ||||||
|  | # COPY aqua.yaml /tmp/aqua.yaml | ||||||
|  | # RUN chown "${USER_ID}:${GROUP_ID}" /tmp/aqua.yaml \ | ||||||
|  | #     && su - "${USERNAME}" -c 'mkdir -p ~/.config/aquaproj-aqua' \ | ||||||
|  | #     && su - "${USERNAME}" -c 'cp /tmp/aqua.yaml ~/.config/aquaproj-aqua/aqua.yaml' \ | ||||||
|  | #     && AQUA_GLOBAL_CONFIG=/tmp/aqua.yaml aqua install \ | ||||||
|  | #     && su - "${USERNAME}" -c 'AQUA_GLOBAL_CONFIG=~/.config/aquaproj-aqua/aqua.yaml aqua install' | ||||||
|  |  | ||||||
|  | # Install toolbox-specific npm packages here | ||||||
|  | # Example: | ||||||
|  | # RUN mise exec -- npm install -g @scope/package@version | ||||||
|  |  | ||||||
| # Remove sudo to ensure no root escalation is possible at runtime | # 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 | 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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ Current state: | |||||||
| - See ../PROMPT for shared toolbox contribution expectations (documentation sync, build cadence, commit/push discipline, Conventional Commits, atomic history). | - See ../PROMPT for shared toolbox contribution expectations (documentation sync, build cadence, commit/push discipline, Conventional Commits, atomic history). | ||||||
|  |  | ||||||
| Collaboration checklist: | Collaboration checklist: | ||||||
| 1. Build upon the base tooling with {{toolbox_name}}-specific additions; mirror outcomes in README.md and this PROMPT. | 1. Translate SEED goals into concrete tooling decisions; mirror outcomes in README.md and this PROMPT (do not rewrite SEED unless the scope resets). | ||||||
| 2. Prefer aqua-managed CLIs and mise-managed runtimes for reproducibility. | 2. Prefer aqua-managed CLIs and mise-managed runtimes for reproducibility. | ||||||
| 3. After each tooling change, update README/PROMPT, run ./build.sh, commit (Conventional Commit message, focused diff), and push only once the build succeeds per ../PROMPT. | 3. After each tooling change, update README/PROMPT, run ./build.sh, commit (Conventional Commit message, focused diff), and push only once the build succeeds per ../PROMPT. | ||||||
| 4. Record verification steps (build/test commands) as they are performed. | 4. Record verification steps (build/test commands) as they are performed. | ||||||
|   | |||||||
| @@ -23,7 +23,7 @@ This SEED file defines the high-level objectives for all toolboxes created from | |||||||
| - **Dockerfile**: Extend from base with toolbox-specific tooling | - **Dockerfile**: Extend from base with toolbox-specific tooling | ||||||
| - **docker-compose.yml**: Configure service with inherited + custom settings | - **docker-compose.yml**: Configure service with inherited + custom settings | ||||||
| - **build.sh**: Wrapper around `docker build` with UID/GID mapping | - **build.sh**: Wrapper around `docker build` with UID/GID mapping | ||||||
| - **run.sh**: Helper to bring service up/down with proper directory setup | - **run.sh**: Helper to bring service up/down | ||||||
| - **devcontainer.json**: VS Code remote container definition | - **devcontainer.json**: VS Code remote container definition | ||||||
| - **SEED**: Define toolbox-specific objectives (this file) | - **SEED**: Define toolbox-specific objectives (this file) | ||||||
| - **PROMPT**: LLM onboarding prompt for future contributors | - **PROMPT**: LLM onboarding prompt for future contributors | ||||||
|   | |||||||
| @@ -5,4 +5,18 @@ registries: | |||||||
| packages: | packages: | ||||||
|   # Add additional packages specific to your toolbox here |   # Add additional packages specific to your toolbox here | ||||||
|   # Example: |   # Example: | ||||||
|   # - name: cli/cli@v2.82.1 |   # - name: cli/cli@v2.82.1 | ||||||
|  |   # - name: jesseduffield/lazygit@v0.55.1 | ||||||
|  |   # - name: direnv/direnv@v2.37.1 | ||||||
|  |   # - name: dandavison/delta@0.18.2 | ||||||
|  |   # - name: ajeetdsouza/zoxide@v0.9.8 | ||||||
|  |   # - name: casey/just@1.43.0 | ||||||
|  |   # - name: mikefarah/yq@v4.48.1 | ||||||
|  |   # - name: ducaale/xh@v0.25.0 | ||||||
|  |   # - name: rs/curlie@v1.8.2 | ||||||
|  |   # - name: twpayne/chezmoi@v2.66.1 | ||||||
|  |   # - name: mvdan/sh@v3.12.0 | ||||||
|  |   # - name: koalaman/shellcheck@v0.11.0 | ||||||
|  |   # - name: hadolint/hadolint@v2.14.0 | ||||||
|  |   # - name: astral-sh/uv@0.9.6 | ||||||
|  |   # - name: watchexec/watchexec@v2.3.2 | ||||||
| @@ -29,7 +29,6 @@ fi | |||||||
| TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}" | TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}" | ||||||
| sanitized_input "$TOOLBOX_NAME" | sanitized_input "$TOOLBOX_NAME" | ||||||
| IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}" | IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}" | ||||||
| sanitized_input "$IMAGE_NAME" |  | ||||||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||||||
|  |  | ||||||
| # Sanitize user input | # Sanitize user input | ||||||
| @@ -44,21 +43,46 @@ sanitized_input "$TEA_VERSION" | |||||||
| BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}" | BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}" | ||||||
| sanitized_input "$BUILDER_NAME" | sanitized_input "$BUILDER_NAME" | ||||||
| CACHE_DIR="${SCRIPT_DIR}/.build-cache" | CACHE_DIR="${SCRIPT_DIR}/.build-cache" | ||||||
|  | TAG="${TAG_OVERRIDE:-dev}" | ||||||
|  | sanitized_input "$TAG" | ||||||
|  | RELEASE_TAG="${RELEASE_TAG_OVERRIDE:-release-current}" | ||||||
|  | sanitized_input "$RELEASE_TAG" | ||||||
|  | VERSION_TAG="${VERSION_TAG_OVERRIDE:-}" | ||||||
|  | if [[ -n "$VERSION_TAG" ]]; then | ||||||
|  |     sanitized_input "$VERSION_TAG" | ||||||
|  | fi | ||||||
|  | PUSH="${PUSH_OVERRIDE:-false}" | ||||||
|  |  | ||||||
| echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}" | echo "Building ${IMAGE_NAME} with UID=${USER_ID} GID=${GROUP_ID} USERNAME=${USERNAME}" | ||||||
|  | echo "Primary tag: ${TAG}" | ||||||
|  |  | ||||||
|  | # Ensure builder exists | ||||||
| if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then | if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then | ||||||
|     echo "Creating builder: ${BUILDER_NAME}" |     echo "Creating builder: ${BUILDER_NAME}" | ||||||
|     docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null |     if ! docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null; then | ||||||
|  |         echo "Error: Failed to create Docker buildx builder." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
| else | else | ||||||
|     echo "Using existing builder: ${BUILDER_NAME}" |     echo "Using existing builder: ${BUILDER_NAME}" | ||||||
|     docker buildx use "${BUILDER_NAME}" >/dev/null |     if ! docker buildx use "${BUILDER_NAME}" >/dev/null; then | ||||||
|  |         echo "Error: Failed to use Docker buildx builder." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
| mkdir -p "${CACHE_DIR}" | # Ensure cache directory exists | ||||||
|  | if ! mkdir -p "${CACHE_DIR}"; then | ||||||
|  |     echo "Error: Failed to create cache directory: ${CACHE_DIR}" >&2 | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| echo "Starting build..." | echo "Starting build..." | ||||||
| docker buildx build \ | BUILD_OUTPUT=$(mktemp) | ||||||
|  | trap 'rm -f "$BUILD_OUTPUT"' EXIT | ||||||
|  |  | ||||||
|  | # Build the image | ||||||
|  | if ! docker buildx build \ | ||||||
|     --builder "${BUILDER_NAME}" \ |     --builder "${BUILDER_NAME}" \ | ||||||
|     --load \ |     --load \ | ||||||
|     --progress=plain \ |     --progress=plain \ | ||||||
| @@ -68,15 +92,102 @@ docker buildx build \ | |||||||
|     --build-arg TEA_VERSION="${TEA_VERSION}" \ |     --build-arg TEA_VERSION="${TEA_VERSION}" \ | ||||||
|     --cache-from "type=local,src=${CACHE_DIR}" \ |     --cache-from "type=local,src=${CACHE_DIR}" \ | ||||||
|     --cache-to "type=local,dest=${CACHE_DIR},mode=max" \ |     --cache-to "type=local,dest=${CACHE_DIR},mode=max" \ | ||||||
|     --tag "${IMAGE_NAME}" \ |     --tag "${IMAGE_NAME}:${TAG}" \ | ||||||
|     "${SCRIPT_DIR}" |     "${SCRIPT_DIR}" 2>&1 | tee "${BUILD_OUTPUT}"; then | ||||||
|  |     echo "Error: Docker build failed. Check output above for details." >&2 | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
| echo "Build completed successfully." | echo "Build completed successfully." | ||||||
|  |  | ||||||
|  | # Run post-build verification | ||||||
|  | echo "Running post-build verification..." | ||||||
|  | if ! docker run --rm "${IMAGE_NAME}:${TAG}" zsh -c 'echo "Container starts successfully"'; then | ||||||
|  |     echo "Error: Failed to start container with basic test." >&2 | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Verify critical tools are available | ||||||
|  | echo "Verifying critical tools..." | ||||||
|  | CRITICAL_TOOLS=("zsh" "git" "curl" "jq" "fish" "fzf" "bat" "fd" "rg" "htop" "btop") | ||||||
|  | for tool in "${CRITICAL_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Error: Critical tool '$tool' not found in PATH." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Verify aqua tools are available | ||||||
|  | echo "Verifying aqua tools..." | ||||||
|  | AQUA_TOOLS=("gh" "lazygit" "direnv" "delta" "zoxide" "just" "yq" "xh" "curlie" "chezmoi" "shfmt" "shellcheck" "hadolint" "uv" "uvx" "watchexec" "kroki") | ||||||
|  | for tool in "${AQUA_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Error: Aqua tool '$tool' not found in PATH." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Verify AI CLI tools are available | ||||||
|  | echo "Verifying AI CLI tools..." | ||||||
|  | AI_TOOLS=("code" "qwen" "gemini" "codex" "opencode") | ||||||
|  | for tool in "${AI_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Error: AI CLI tool '$tool' not found in PATH." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | # Verify testing tools are available | ||||||
|  | echo "Verifying testing tools..." | ||||||
|  | TESTING_TOOLS=("bats" "shellcheck" "shfmt" "hadolint") | ||||||
|  | for tool in "${TESTING_TOOLS[@]}"; do | ||||||
|  |     if ! docker run --rm "${IMAGE_NAME}:${TAG}" which "$tool" >/dev/null 2>&1; then | ||||||
|  |         echo "Error: Testing tool '$tool' not found in PATH." >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  | done | ||||||
|  |  | ||||||
|  | echo "All verifications passed." | ||||||
|  |  | ||||||
|  | # Push if requested | ||||||
|  | if [[ "${PUSH}" == "true" ]]; then | ||||||
|  |     echo "Pushing ${IMAGE_NAME}:${TAG}" | ||||||
|  |     if ! docker push "${IMAGE_NAME}:${TAG}"; then | ||||||
|  |         echo "Error: Failed to push ${IMAGE_NAME}:${TAG}" >&2 | ||||||
|  |         exit 1 | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if [[ "${TAG}" == "dev" && -n "${VERSION_TAG}" ]]; then | ||||||
|  |         if ! docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${VERSION_TAG}"; then | ||||||
|  |             echo "Error: Failed to tag ${IMAGE_NAME}:${VERSION_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |         echo "Pushing ${IMAGE_NAME}:${VERSION_TAG}" | ||||||
|  |         if ! docker push "${IMAGE_NAME}:${VERSION_TAG}"; then | ||||||
|  |             echo "Error: Failed to push ${IMAGE_NAME}:${VERSION_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if [[ "${TAG}" == "dev" ]]; then | ||||||
|  |         if ! docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${RELEASE_TAG}"; then | ||||||
|  |             echo "Error: Failed to tag ${IMAGE_NAME}:${RELEASE_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |         echo "Pushing ${IMAGE_NAME}:${RELEASE_TAG}" | ||||||
|  |         if ! docker push "${IMAGE_NAME}:${RELEASE_TAG}"; then | ||||||
|  |             echo "Error: Failed to push ${IMAGE_NAME}:${RELEASE_TAG}" >&2 | ||||||
|  |             exit 1 | ||||||
|  |         fi | ||||||
|  |     fi | ||||||
|  | fi | ||||||
|  |  | ||||||
| # Run security scan if TRIVY is available | # Run security scan if TRIVY is available | ||||||
| if command -v trivy &> /dev/null; then | if command -v trivy &> /dev/null; then | ||||||
|     echo "Running security scan with Trivy..." |     echo "Running security scan with Trivy..." | ||||||
|     trivy image --exit-code 0 --severity HIGH,CRITICAL "${IMAGE_NAME}" |     trivy image --exit-code 0 --severity HIGH,CRITICAL "${IMAGE_NAME}:${TAG}" | ||||||
| else | else | ||||||
|     echo "Trivy not found. Install Trivy to perform security scanning." |     echo "Trivy not found. Install Trivy to perform security scanning." | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | echo "Build process completed successfully with all verifications." | ||||||
| @@ -32,15 +32,4 @@ services: | |||||||
|       - ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw |       - ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw | ||||||
|       # Additional AI tool directories |       # Additional AI tool directories | ||||||
|       - ${HOME}/.config/codex:/home/toolbox/.config/codex:rw |       - ${HOME}/.config/codex:/home/toolbox/.config/codex:rw | ||||||
|       - ${HOME}/.cache/codex:/home/toolbox/.cache/codex:rw |       - ${HOME}/.cache/codex:/home/toolbox/.cache/codex:rw | ||||||
|       # AI CLI tool configuration and cache directories |  | ||||||
|       - ${HOME}/.config/openai:/home/toolbox/.config/openai:rw |  | ||||||
|       - ${HOME}/.config/gemini:/home/toolbox/.config/gemini:rw |  | ||||||
|       - ${HOME}/.config/qwen:/home/toolbox/.config/qwen:rw |  | ||||||
|       - ${HOME}/.config/code:/home/toolbox/.config/code:rw |  | ||||||
|       - ${HOME}/.config/opencode:/home/toolbox/.config/opencode:rw |  | ||||||
|       - ${HOME}/.cache/openai:/home/toolbox/.cache/openai:rw |  | ||||||
|       - ${HOME}/.cache/gemini:/home/toolbox/.cache/gemini:rw |  | ||||||
|       - ${HOME}/.cache/qwen:/home/toolbox/.cache/qwen:rw |  | ||||||
|       - ${HOME}/.cache/code:/home/toolbox/.cache/code:rw |  | ||||||
|       - ${HOME}/.cache/opencode:/home/toolbox/.cache/opencode:rw |  | ||||||
| @@ -10,9 +10,12 @@ Examples: | |||||||
|   ./release.sh 0.2.0 |   ./release.sh 0.2.0 | ||||||
|   ./release.sh --dry-run 0.2.0 |   ./release.sh --dry-run 0.2.0 | ||||||
|  |  | ||||||
| This script promotes the dev tag to: | This script rebuilds the toolbox image, tags it as: | ||||||
|  |   - tsysdevstack-toolboxstack-<name>:dev | ||||||
|   - tsysdevstack-toolboxstack-<name>:release-current |   - tsysdevstack-toolboxstack-<name>:release-current | ||||||
|   - tsysdevstack-toolboxstack-<name>:v<semver> |   - tsysdevstack-toolboxstack-<name>:v<semver> | ||||||
|  |  | ||||||
|  | When run without --dry-run it pushes all three tags. | ||||||
| EOU | EOU | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -71,32 +74,38 @@ elif [[ -z "${REPO_ROOT}" ]]; then | |||||||
|     echo "Warning: unable to resolve git repository root; skipping clean tree check." >&2 |     echo "Warning: unable to resolve git repository root; skipping clean tree check." >&2 | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # Get the toolbox name from the directory name | # Get the toolbox name from the directory name (or you can pass it as an argument) | ||||||
| TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}" | TOOLBOX_NAME="${TOOLBOX_NAME_OVERRIDE:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")}" | ||||||
| IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}" | IMAGE_NAME="tsysdevstack-toolboxstack-${TOOLBOX_NAME#toolbox-}" | ||||||
|  | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||||||
|  |  | ||||||
|  | USER_ID="${USER_ID_OVERRIDE:-$(id -u)}" | ||||||
|  | GROUP_ID="${GROUP_ID_OVERRIDE:-$(id -g)}" | ||||||
|  | USERNAME="${USERNAME_OVERRIDE:-toolbox}" | ||||||
|  | TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}" | ||||||
|  | BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}" | ||||||
|  | CACHE_DIR="${SCRIPT_DIR}/.build-cache" | ||||||
|  | TAG="${TAG_OVERRIDE:-dev}" | ||||||
|  | RELEASE_TAG="${RELEASE_TAG_OVERRIDE:-release-current}" | ||||||
|  | VERSION_TAG="${VERSION_TAG_OVERRIDE:-}" | ||||||
|  | if [[ -n "$VERSION_TAG" ]]; then | ||||||
|  |     VERSION_TAG="$SEMVER" | ||||||
|  | fi | ||||||
|  | PUSH="${PUSH_OVERRIDE:-false}" | ||||||
|  |  | ||||||
| echo "Preparing release for ${SEMVER}" | echo "Preparing release for ${SEMVER}" | ||||||
| echo "  dry-run: ${DRY_RUN}" | echo "  dry-run: ${DRY_RUN}" | ||||||
| echo "  allow-dirty: ${ALLOW_DIRTY}" | echo "  allow-dirty: ${ALLOW_DIRTY}" | ||||||
|  |  | ||||||
| # First, ensure we have the dev tag built |  | ||||||
| if [[ "${DRY_RUN}" == "true" ]]; then | if [[ "${DRY_RUN}" == "true" ]]; then | ||||||
|     echo "[dry-run] Would build dev tag" |     echo "[dry-run] Would build ${IMAGE_NAME}:${TAG}" | ||||||
|  |     TAG_OVERRIDE="${TAG}" PUSH_OVERRIDE=false "${SCRIPT_DIR}/build.sh" | ||||||
|  |     echo "[dry-run] Skipped pushing tags." | ||||||
| else | else | ||||||
|     echo "Building dev tag..." |     echo "Building ${IMAGE_NAME}:${TAG}" | ||||||
|     "${SCRIPT_DIR}/build.sh" |     TAG_OVERRIDE="${TAG}" PUSH_OVERRIDE=true RELEASE_TAG_OVERRIDE="${RELEASE_TAG}" VERSION_TAG_OVERRIDE="${SEMVER}" "${SCRIPT_DIR}/build.sh" | ||||||
| fi |     echo "Release ${SEMVER} pushed as:" | ||||||
|  |     echo "  - ${IMAGE_NAME}:dev" | ||||||
| # 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}:release-current" | ||||||
|     echo "  - ${IMAGE_NAME}:${SEMVER}" |     echo "  - ${IMAGE_NAME}:${SEMVER}" | ||||||
| fi | fi | ||||||
| @@ -28,13 +28,14 @@ fi | |||||||
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||||||
| COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml" | COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml" | ||||||
|  |  | ||||||
| # Sanitize user input |  | ||||||
| export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}" | export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}" | ||||||
| sanitized_input "$LOCAL_UID" | sanitized_input "$LOCAL_UID" | ||||||
| export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}" | export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}" | ||||||
| sanitized_input "$LOCAL_GID" | sanitized_input "$LOCAL_GID" | ||||||
| export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}" | export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}" | ||||||
| sanitized_input "$LOCAL_USERNAME" | sanitized_input "$LOCAL_USERNAME" | ||||||
|  | export TOOLBOX_IMAGE="${TOOLBOX_IMAGE_OVERRIDE:-tsysdevstack-toolboxstack-{{toolbox_name}}}" | ||||||
|  | sanitized_input "$TOOLBOX_IMAGE" | ||||||
|  |  | ||||||
| if [[ ! -f "${COMPOSE_FILE}" ]]; then | if [[ ! -f "${COMPOSE_FILE}" ]]; then | ||||||
|     echo "Error: docker-compose.yml not found at ${COMPOSE_FILE}" >&2 |     echo "Error: docker-compose.yml not found at ${COMPOSE_FILE}" >&2 | ||||||
| @@ -51,6 +52,7 @@ if [[ "${ACTION}" == "up" ]]; then | |||||||
|     mkdir -p "${HOME}/.config" "${HOME}/.local/share" |     mkdir -p "${HOME}/.config" "${HOME}/.local/share" | ||||||
|     mkdir -p "${HOME}/.cache/openai" "${HOME}/.cache/gemini" "${HOME}/.cache/qwen" "${HOME}/.cache/code" "${HOME}/.cache/opencode" |     mkdir -p "${HOME}/.cache/openai" "${HOME}/.cache/gemini" "${HOME}/.cache/qwen" "${HOME}/.cache/code" "${HOME}/.cache/opencode" | ||||||
|     mkdir -p "${HOME}/.config/openai" "${HOME}/.config/gemini" "${HOME}/.config/qwen" "${HOME}/.config/code" "${HOME}/.config/opencode" |     mkdir -p "${HOME}/.config/openai" "${HOME}/.config/gemini" "${HOME}/.config/qwen" "${HOME}/.config/code" "${HOME}/.config/opencode" | ||||||
|  |     mkdir -p "${HOME}/.config/codex" "${HOME}/.cache/codex" | ||||||
|      |      | ||||||
|     # Set proper permissions for created directories |     # Set proper permissions for created directories | ||||||
|     chmod 700 "${HOME}/.config" "${HOME}/.local/share" "${HOME}/.cache" 2>/dev/null || true |     chmod 700 "${HOME}/.config" "${HOME}/.local/share" "${HOME}/.cache" 2>/dev/null || true | ||||||
| @@ -59,7 +61,7 @@ fi | |||||||
| case "${ACTION}" in | case "${ACTION}" in | ||||||
|     up) |     up) | ||||||
|         docker compose -f "${COMPOSE_FILE}" up --build --detach "$@" |         docker compose -f "${COMPOSE_FILE}" up --build --detach "$@" | ||||||
|         echo "Container started. Use 'docker exec -it $(basename "$SCRIPT_DIR" | sed 's/toolbox-//') zsh' to access the shell." |         echo "Container started. Use 'docker exec -it tsysdevstack-toolboxstack-{{toolbox_name}} zsh' to access the shell." | ||||||
|         ;; |         ;; | ||||||
|     down) |     down) | ||||||
|         docker compose -f "${COMPOSE_FILE}" down "$@" |         docker compose -f "${COMPOSE_FILE}" down "$@" | ||||||
| @@ -69,4 +71,4 @@ case "${ACTION}" in | |||||||
|         echo "Usage: $0 [up|down] [additional docker compose args]" >&2 |         echo "Usage: $0 [up|down] [additional docker compose args]" >&2 | ||||||
|         exit 1 |         exit 1 | ||||||
|         ;; |         ;; | ||||||
| esac | esac | ||||||
		Reference in New Issue
	
	Block a user