feat(toolbox): update toolbox configuration and scripts
- Update collab/TSYSDevStack-toolbox-prompt.md with latest guidelines - Update output/PROMPT with improved instructions for AI collaboration - Update output/toolbox-base/PROMPT with enhanced development guidelines - Update output/toolbox-base/README.md with current documentation - Update output/toolbox-base/build.sh with improved build process - Update output/toolbox-base/docker-compose.yml with refined service definitions - Update output/toolbox-base/run.sh with enhanced runtime configuration - Add output/toolbox-base/release.sh for release management processes These changes improve the developer workspace experience and ensure consistent tooling across the TSYSDevStack project.
This commit is contained in:
@@ -25,7 +25,7 @@ The TSYSDevStack consists of four categories:
|
|||||||
- mise
|
- mise
|
||||||
- zsh / oh-my-zsh / completions /
|
- zsh / oh-my-zsh / completions /
|
||||||
-
|
-
|
||||||
- See `output/PROMPT` for shared toolbox contributor guidance, `output/toolbox-base/PROMPT` for the image-specific snapshot, and `output/NewToolbox.sh` for bootstrapping new toolboxes from the template (edit each toolbox's `SEED` once to set goals, then load its PROMPT when starting work).
|
- See `output/PROMPT` for shared toolbox contributor guidance, `output/toolbox-base/PROMPT` for the image-specific snapshot, and `output/NewToolbox.sh` for bootstrapping new toolboxes from the template (edit each toolbox's `SEED` once to set goals, then load its PROMPT when starting work). Toolbox images follow a `dev` → `release-current` → `vX.Y.Z` tagging scheme; use `build.sh` for local iteration and `release.sh <semver>` (clean tree) to promote builds (details in README).
|
||||||
|
|
||||||
## toolbox-gis
|
## toolbox-gis
|
||||||
## toolbox-weather
|
## toolbox-weather
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ Global toolbox guidance:
|
|||||||
- Keep aqua/mise usage consistent across the family; prefer aqua-managed CLIs and mise-managed runtimes.
|
- Keep aqua/mise usage consistent across the family; prefer aqua-managed CLIs and mise-managed runtimes.
|
||||||
- Reference toolbox-template when bootstrapping a new toolbox. Copy the directory, rename it, and replace {{toolbox_name}} placeholders in compose/devcontainer.
|
- Reference toolbox-template when bootstrapping a new toolbox. Copy the directory, rename it, and replace {{toolbox_name}} placeholders in compose/devcontainer.
|
||||||
- Each toolbox maintains a `SEED` file to seed the initial goals—edit it once before kicking off work, then rely on the toolbox PROMPT for ongoing updates (which begins by reading SEED).
|
- Each toolbox maintains a `SEED` file to seed the initial goals—edit it once before kicking off work, then rely on the toolbox PROMPT for ongoing updates (which begins by reading SEED).
|
||||||
|
- Default build workflow: `./build.sh` produces a `:dev` tag; `./release.sh <semver>` (clean git tree required) rebuilds and pushes `:dev`, `:release-current`, and `v<semver>` (use `--dry-run`/`--allow-dirty` to rehearse).
|
||||||
|
- Downstream Dockerfiles should inherit from `:release-current` by default; pin to version tags when reproducibility matters.
|
||||||
|
|
||||||
Commit discipline:
|
Commit discipline:
|
||||||
- Craft atomic commits with clear intent; do not mix unrelated changes.
|
- Craft atomic commits with clear intent; do not mix unrelated changes.
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ Current state:
|
|||||||
- mise handles language/tool runtimes; activation wired into zsh, bash, and fish.
|
- mise handles language/tool runtimes; activation wired into zsh, bash, and fish.
|
||||||
- docker-compose.yml runs container with host UID/GID, `sleep infinity`, and docker socket mount; run via run.sh/build.sh. Host directories `~/.local/share/mise` and `~/.cache/mise` are mounted for persistent runtimes.
|
- docker-compose.yml runs container with host UID/GID, `sleep infinity`, and docker socket mount; run via run.sh/build.sh. Host directories `~/.local/share/mise` and `~/.cache/mise` are mounted for persistent runtimes.
|
||||||
- Devcontainer config ( .devcontainer/devcontainer.json ) references the compose service.
|
- Devcontainer config ( .devcontainer/devcontainer.json ) references the compose service.
|
||||||
- Documentation: README.md (tooling inventory & workflow) and this PROMPT must stay current, and both should stay aligned with the shared guidance in ../PROMPT. README also notes that build.sh now uses docker buildx with a local cache directory.
|
- Documentation: README.md (tooling inventory & workflow) and this PROMPT must stay current, and both should stay aligned with the shared guidance in ../PROMPT. README also notes that build.sh now uses docker buildx with a local cache directory and documents the `dev` → `release-current` → semantic tagging workflow.
|
||||||
|
|
||||||
Collaboration guidelines:
|
Collaboration guidelines:
|
||||||
1. Default to non-destructive operations; respect existing scripts run.sh/build.sh.
|
1. Default to non-destructive operations; respect existing scripts run.sh/build.sh.
|
||||||
2. Any tooling changes require updating README.md (inventory) and this prompt summary, rebuilding via ./build.sh, then committing (Conventional Commits, atomic diffs) and pushing after a successful build per ../PROMPT.
|
2. Any tooling changes require updating README.md (inventory) and this prompt summary, rebuilding via `./build.sh` (local dev tag), then committing (Conventional Commits, atomic diffs) and pushing after a successful build per ../PROMPT. Use `./release.sh <semver>` (clean git tree required; `--dry-run`/`--allow-dirty` only for rehearsal) to promote to `release-current` + semantic tag.
|
||||||
3. Keep configurations reproducible: prefer aqua/mise for new CLI/runtimes over apt unless prerequisites.
|
3. Keep configurations reproducible: prefer aqua/mise for new CLI/runtimes over apt unless prerequisites.
|
||||||
4. Mention verification steps (build/test) after changes.
|
4. Mention verification steps (build/test) after changes and note which tag was built/pushed.
|
||||||
5. Maintain UID/GID mapping and non-root execution.
|
5. Downstream consumers should inherit from `:release-current` (or a pinned semantic tag); maintain UID/GID mapping and non-root execution.
|
||||||
|
|
||||||
Active focus:
|
Active focus:
|
||||||
- Extend toolbox-base as a "daily driver" dev container while preserving reproducibility and documentation.
|
- Extend toolbox-base as a "daily driver" dev container while preserving reproducibility and documentation.
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ Daily-driver development container for ToolboxStack work. It provides a reproduc
|
|||||||
|
|
||||||
## 🚀 Quick Start
|
## 🚀 Quick Start
|
||||||
|
|
||||||
1. **Build the image**
|
1. **Build the image (local dev tag)**
|
||||||
```bash
|
```bash
|
||||||
./build.sh
|
./build.sh
|
||||||
```
|
```
|
||||||
> Uses `docker buildx` with a local cache at `.build-cache/` for faster rebuilds.
|
> Builds and tags the image as `tsysdevstack-toolboxstack-toolbox-base:dev`. Uses `docker buildx` with a local cache at `.build-cache/` for faster rebuilds.
|
||||||
2. **Start the container**
|
2. **Start the container**
|
||||||
```bash
|
```bash
|
||||||
./run.sh up
|
./run.sh up
|
||||||
```
|
```
|
||||||
> Mise runtimes persist to your host in `~/.local/share/mise` and `~/.cache/mise` so language/tool downloads are shared across projects.
|
> Defaults to the `release-current` tag; override with `TOOLBOX_IMAGE_OVERRIDE=...` when testing other tags. Mise runtimes persist to your host in `~/.local/share/mise` and `~/.cache/mise` so language/tool downloads are shared across projects.
|
||||||
3. **Attach to a shell**
|
3. **Attach to a shell**
|
||||||
```bash
|
```bash
|
||||||
docker exec -it tsysdevstack-toolboxstack-toolbox-base zsh
|
docker exec -it tsysdevstack-toolboxstack-toolbox-base zsh
|
||||||
@@ -30,6 +30,15 @@ The compose service mounts the current repo to `/workspace` (read/write) and run
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🏷️ Image Tagging & Releases
|
||||||
|
|
||||||
|
- `./build.sh` (no overrides) ⇒ builds `:dev` for active development.
|
||||||
|
- `./release.sh <semver>` ⇒ rebuilds, retags, and pushes `:dev`, `:release-current`, and `v<semver>` (e.g., `./release.sh 0.2.0`). Requires a clean git tree.
|
||||||
|
- Add `--dry-run` to rehearse the release without pushing (optionally `--allow-dirty` for experimentation only).
|
||||||
|
- Downstream Dockerfiles should inherit from `tsysdevstack-toolboxstack-toolbox-base:release-current` (or pin to a semantic tag for reproducibility).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🧩 Tooling Inventory
|
## 🧩 Tooling Inventory
|
||||||
|
|
||||||
| Category | Tooling | Notes |
|
| Category | Tooling | Notes |
|
||||||
|
|||||||
@@ -11,8 +11,13 @@ USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
|||||||
TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}"
|
TEA_VERSION="${TEA_VERSION_OVERRIDE:-0.11.1}"
|
||||||
BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}"
|
BUILDER_NAME="${BUILDER_NAME:-tsysdevstack-toolboxstack-builder}"
|
||||||
CACHE_DIR="${SCRIPT_DIR}/.build-cache"
|
CACHE_DIR="${SCRIPT_DIR}/.build-cache"
|
||||||
|
TAG="${TAG_OVERRIDE:-dev}"
|
||||||
|
RELEASE_TAG="${RELEASE_TAG_OVERRIDE:-release-current}"
|
||||||
|
VERSION_TAG="${VERSION_TAG_OVERRIDE:-}"
|
||||||
|
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}"
|
||||||
|
|
||||||
if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then
|
if ! docker buildx inspect "${BUILDER_NAME}" >/dev/null 2>&1; then
|
||||||
docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null
|
docker buildx create --driver docker-container --name "${BUILDER_NAME}" --use >/dev/null
|
||||||
@@ -32,5 +37,22 @@ 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}"
|
||||||
|
|
||||||
|
if [[ "${PUSH}" == "true" ]]; then
|
||||||
|
echo "Pushing ${IMAGE_NAME}:${TAG}"
|
||||||
|
docker push "${IMAGE_NAME}:${TAG}"
|
||||||
|
|
||||||
|
if [[ "${TAG}" == "dev" && -n "${VERSION_TAG}" ]]; then
|
||||||
|
docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${VERSION_TAG}"
|
||||||
|
echo "Pushing ${IMAGE_NAME}:${VERSION_TAG}"
|
||||||
|
docker push "${IMAGE_NAME}:${VERSION_TAG}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${TAG}" == "dev" ]]; then
|
||||||
|
docker tag "${IMAGE_NAME}:${TAG}" "${IMAGE_NAME}:${RELEASE_TAG}"
|
||||||
|
echo "Pushing ${IMAGE_NAME}:${RELEASE_TAG}"
|
||||||
|
docker push "${IMAGE_NAME}:${RELEASE_TAG}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
toolbox-base:
|
toolbox-base:
|
||||||
container_name: tsysdevstack-toolboxstack-toolbox-base
|
container_name: tsysdevstack-toolboxstack-toolbox-base
|
||||||
image: tsysdevstack-toolboxstack-toolbox-base
|
image: ${TOOLBOX_IMAGE:-tsysdevstack-toolboxstack-toolbox-base:release-current}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
args:
|
args:
|
||||||
|
|||||||
90
ToolboxStack/output/toolbox-base/release.sh
Executable file
90
ToolboxStack/output/toolbox-base/release.sh
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/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 rebuilds the toolbox-base image, tags it as:
|
||||||
|
- tsysdevstack-toolboxstack-toolbox-base:dev
|
||||||
|
- tsysdevstack-toolboxstack-toolbox-base:release-current
|
||||||
|
- tsysdevstack-toolboxstack-toolbox-base:v<semver>
|
||||||
|
|
||||||
|
When run without --dry-run it pushes all three tags.
|
||||||
|
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
|
||||||
|
|
||||||
|
echo "Preparing release for ${SEMVER}"
|
||||||
|
echo " dry-run: ${DRY_RUN}"
|
||||||
|
echo " allow-dirty: ${ALLOW_DIRTY}"
|
||||||
|
|
||||||
|
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||||
|
VERSION_TAG_OVERRIDE="${SEMVER}" PUSH_OVERRIDE=false "${SCRIPT_DIR}/build.sh"
|
||||||
|
echo "[dry-run] Skipped pushing tags."
|
||||||
|
else
|
||||||
|
VERSION_TAG_OVERRIDE="${SEMVER}" PUSH_OVERRIDE=true "${SCRIPT_DIR}/build.sh"
|
||||||
|
echo "Release ${SEMVER} pushed as:"
|
||||||
|
echo " - tsysdevstack-toolboxstack-toolbox-base:dev"
|
||||||
|
echo " - tsysdevstack-toolboxstack-toolbox-base:release-current"
|
||||||
|
echo " - tsysdevstack-toolboxstack-toolbox-base:${SEMVER}"
|
||||||
|
fi
|
||||||
@@ -8,6 +8,7 @@ COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.yml"
|
|||||||
export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}"
|
export LOCAL_UID="${USER_ID_OVERRIDE:-$(id -u)}"
|
||||||
export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}"
|
export LOCAL_GID="${GROUP_ID_OVERRIDE:-$(id -g)}"
|
||||||
export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
export LOCAL_USERNAME="${USERNAME_OVERRIDE:-toolbox}"
|
||||||
|
export TOOLBOX_IMAGE="${TOOLBOX_IMAGE_OVERRIDE:-tsysdevstack-toolboxstack-toolbox-base:release-current}"
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
Reference in New Issue
Block a user