From d254ba169d989dc945871633ce7b67650f1ba536 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 15:39:51 -0800 Subject: [PATCH 01/11] add snapshot tests for build plan of examples --- core/__snapshots__/core_test.snap | 3189 +++++++++++++++++ core/core_test.go | 44 + core/generate/__snapshots__/context_test.snap | 4 +- core/generate/command_step_builder.go | 8 +- core/generate/context.go | 5 +- core/generate/context_test.go | 4 +- core/mise/mise.go | 3 +- 7 files changed, 3249 insertions(+), 8 deletions(-) create mode 100755 core/__snapshots__/core_test.snap create mode 100644 core/core_test.go diff --git a/core/__snapshots__/core_test.snap b/core/__snapshots__/core_test.snap new file mode 100755 index 0000000..049777e --- /dev/null +++ b/core/__snapshots__/core_test.snap @@ -0,0 +1,3189 @@ + +[TestGenerateBuildPlanForExamples/config-file - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "neofetch", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.python]\n version = \"3.13.2\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: python" + } + ], + "dependsOn": [ + "packages:apt:config" + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "PIP_CACHE_DIR", + "value": "/opt/pip-cache" + }, + { + "name": "PIP_DEFAULT_TIMEOUT", + "value": "100" + }, + { + "name": "PIP_DISABLE_PIP_VERSION_CHECK", + "value": "1" + }, + { + "name": "PYTHONDONTWRITEBYTECODE", + "value": "1" + }, + { + "name": "PYTHONFAULTHANDLER", + "value": "1" + }, + { + "name": "PYTHONHASHSEED", + "value": "random" + }, + { + "name": "PYTHONUNBUFFERED", + "value": "1" + }, + { + "path": "/root/.local/bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [], + "dependsOn": [ + "packages:mise", + "setup", + "packages:apt:python-system-deps" + ], + "name": "install" + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y pkg-config'", + "customName": "install apt packages: pkg-config" + } + ], + "name": "packages:apt:python-system-deps", + "useSecrets": false + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y neofetch'", + "customName": "install apt packages: neofetch" + } + ], + "name": "packages:apt:config", + "useSecrets": false + }, + { + "commands": [ + { + "cmd": "sh -c 'neofetch'" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "build" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/go-cmd-dirs - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "go-build": { + "directory": "/root/.cache/go-build", + "type": "shared" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "baseImage": "alpine:latest", + "cmd": "./out", + "outputs": [ + "out" + ], + "variables": { + "GIN_MODE": "release" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.go]\n version = \"1.18\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: go" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "dest": "go.mod", + "src": "go.mod" + }, + { + "dest": "go.sum", + "src": "go.sum" + }, + { + "caches": [ + "go-build" + ], + "cmd": "go mod download" + }, + { + "name": "CGO_ENABLED", + "value": "0" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "install" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "caches": [ + "go-build" + ], + "cmd": "go build -o out ./cmd/server" + } + ], + "dependsOn": [ + "packages:mise", + "install" + ], + "name": "build" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/go-mod - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "go-build": { + "directory": "/root/.cache/go-build", + "type": "shared" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "baseImage": "alpine:latest", + "cmd": "./out", + "outputs": [ + "out" + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.go]\n version = \"1.23.6\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: go" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "dest": "go.mod", + "src": "go.mod" + }, + { + "dest": "go.sum", + "src": "go.sum" + }, + { + "caches": [ + "go-build" + ], + "cmd": "go mod download" + }, + { + "name": "CGO_ENABLED", + "value": "0" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "install" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "caches": [ + "go-build" + ], + "cmd": "go build -o out" + } + ], + "dependsOn": [ + "packages:mise", + "install" + ], + "name": "build" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/node-bun - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "bun-install": { + "directory": "/root/.bun/install/cache", + "type": "shared" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "bun index.ts", + "outputs": [ + "." + ], + "variables": { + "CI": "true", + "NODE_ENV": "production", + "NPM_CONFIG_PRODUCTION": "false", + "YARN_PRODUCTION": "false" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.bun]\n version = \"1.2.2\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: bun" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "dest": "bun.lockb", + "src": "bun.lockb" + }, + { + "caches": [ + "bun-install" + ], + "cmd": "bun install --frozen-lockfile" + } + ], + "dependsOn": [ + "packages:mise", + "setup" + ], + "name": "install" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "cmd": "bun run build" + } + ], + "dependsOn": [ + "install" + ], + "name": "build" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/node-corepack - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "pnpm-install": { + "directory": "/root/.local/share/pnpm/store/v3", + "type": "shared" + } + }, + "start": { + "cmd": "pnpm run start", + "outputs": [ + "." + ], + "variables": { + "CI": "true", + "NODE_ENV": "production", + "NPM_CONFIG_PRODUCTION": "false", + "YARN_PRODUCTION": "false" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"20.18.2\"\n [tools.pnpm]\n version = \"10.2.0\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, pnpm" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "cmd": "corepack enable" + }, + { + "cmd": "corepack prepare --activate" + } + ], + "dependsOn": [ + "packages:mise", + "setup" + ], + "name": "corepack" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "dest": "pnpm-lock.yaml", + "src": "pnpm-lock.yaml" + }, + { + "caches": [ + "pnpm-install" + ], + "cmd": "pnpm install --frozen-lockfile --prod=false" + } + ], + "dependsOn": [ + "packages:mise", + "setup", + "corepack" + ], + "name": "install" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "cmd": "pnpm run build" + } + ], + "dependsOn": [ + "install" + ], + "name": "build" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/node-pnpm-workspaces - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "node index.js", + "outputs": [ + "." + ], + "variables": { + "CI": "true", + "NODE_ENV": "production", + "NPM_CONFIG_PRODUCTION": "false", + "YARN_PRODUCTION": "false" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.pnpm]\n version = \"10.2.0\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, pnpm" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/python-pdm - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "python main.py", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.2\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: pipx, python" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "PIP_CACHE_DIR", + "value": "/opt/pip-cache" + }, + { + "name": "PIP_DEFAULT_TIMEOUT", + "value": "100" + }, + { + "name": "PIP_DISABLE_PIP_VERSION_CHECK", + "value": "1" + }, + { + "name": "PYTHONDONTWRITEBYTECODE", + "value": "1" + }, + { + "name": "PYTHONFAULTHANDLER", + "value": "1" + }, + { + "name": "PYTHONHASHSEED", + "value": "random" + }, + { + "name": "PYTHONUNBUFFERED", + "value": "1" + }, + { + "path": "/root/.local/bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "cmd": "pipx install pdm" + }, + { + "name": "PDM_CHECK_UPDATE", + "value": "false" + }, + { + "dest": "pyproject.toml", + "src": "pyproject.toml" + }, + { + "dest": "pdm.lock", + "src": "pdm.lock" + }, + { + "dest": ".", + "src": "." + }, + { + "cmd": "pdm install --check --prod --no-editable" + }, + { + "path": "/app/.venv/bin" + } + ], + "dependsOn": [ + "packages:mise", + "setup", + "packages:apt:python-system-deps" + ], + "name": "install" + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y pkg-config'", + "customName": "install apt packages: pkg-config" + } + ], + "name": "packages:apt:python-system-deps", + "useSecrets": false + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/python-pip - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "pip": { + "directory": "/opt/pip-cache", + "type": "shared" + } + }, + "start": { + "cmd": "python main.py", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.python]\n version = \"3.13.2\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: python" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "PIP_CACHE_DIR", + "value": "/opt/pip-cache" + }, + { + "name": "PIP_DEFAULT_TIMEOUT", + "value": "100" + }, + { + "name": "PIP_DISABLE_PIP_VERSION_CHECK", + "value": "1" + }, + { + "name": "PYTHONDONTWRITEBYTECODE", + "value": "1" + }, + { + "name": "PYTHONFAULTHANDLER", + "value": "1" + }, + { + "name": "PYTHONHASHSEED", + "value": "random" + }, + { + "name": "PYTHONUNBUFFERED", + "value": "1" + }, + { + "path": "/root/.local/bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "requirements.txt", + "src": "requirements.txt" + }, + { + "caches": [ + "pip" + ], + "cmd": "pip install -r requirements.txt" + } + ], + "dependsOn": [ + "packages:mise", + "setup", + "packages:apt:python-system-deps" + ], + "name": "install" + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y pkg-config'", + "customName": "install apt packages: pkg-config" + } + ], + "name": "packages:apt:python-system-deps", + "useSecrets": false + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/python-poetry - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "python main.py", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.2\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: pipx, python" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "PIP_CACHE_DIR", + "value": "/opt/pip-cache" + }, + { + "name": "PIP_DEFAULT_TIMEOUT", + "value": "100" + }, + { + "name": "PIP_DISABLE_PIP_VERSION_CHECK", + "value": "1" + }, + { + "name": "PYTHONDONTWRITEBYTECODE", + "value": "1" + }, + { + "name": "PYTHONFAULTHANDLER", + "value": "1" + }, + { + "name": "PYTHONHASHSEED", + "value": "random" + }, + { + "name": "PYTHONUNBUFFERED", + "value": "1" + }, + { + "path": "/root/.local/bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "cmd": "pipx install poetry" + }, + { + "cmd": "poetry config virtualenvs.create false" + }, + { + "dest": "pyproject.toml", + "src": "pyproject.toml" + }, + { + "dest": "poetry.lock", + "src": "poetry.lock" + }, + { + "cmd": "poetry install --no-interaction --no-ansi --no-root" + } + ], + "dependsOn": [ + "packages:mise", + "setup", + "packages:apt:python-system-deps" + ], + "name": "install" + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y pkg-config'", + "customName": "install apt packages: pkg-config" + } + ], + "name": "packages:apt:python-system-deps", + "useSecrets": false + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/python-system-deps - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "pip": { + "directory": "/opt/pip-cache", + "type": "shared" + } + }, + "start": { + "cmd": "python main.py", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.python]\n version = \"3.11.11\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "dest": "/app/.python-version", + "src": ".python-version" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: python" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise", + "/app/.python-version" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "PIP_CACHE_DIR", + "value": "/opt/pip-cache" + }, + { + "name": "PIP_DEFAULT_TIMEOUT", + "value": "100" + }, + { + "name": "PIP_DISABLE_PIP_VERSION_CHECK", + "value": "1" + }, + { + "name": "PYTHONDONTWRITEBYTECODE", + "value": "1" + }, + { + "name": "PYTHONFAULTHANDLER", + "value": "1" + }, + { + "name": "PYTHONHASHSEED", + "value": "random" + }, + { + "name": "PYTHONUNBUFFERED", + "value": "1" + }, + { + "path": "/root/.local/bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "requirements.txt", + "src": "requirements.txt" + }, + { + "caches": [ + "pip" + ], + "cmd": "pip install -r requirements.txt" + } + ], + "dependsOn": [ + "packages:mise", + "setup", + "packages:apt:python-system-deps" + ], + "name": "install" + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ffmpeg gcc pkg-config poppler-utils'", + "customName": "install apt packages: ffmpeg gcc pkg-config poppler-utils" + } + ], + "name": "packages:apt:python-system-deps", + "useSecrets": false + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/python-uv - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "gunicorn --bind 0.0.0.0:3333 main:app", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.11.11\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "dest": "/app/.python-version", + "src": ".python-version" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: pipx, python" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise", + "/app/.python-version" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "PIP_CACHE_DIR", + "value": "/opt/pip-cache" + }, + { + "name": "PIP_DEFAULT_TIMEOUT", + "value": "100" + }, + { + "name": "PIP_DISABLE_PIP_VERSION_CHECK", + "value": "1" + }, + { + "name": "PYTHONDONTWRITEBYTECODE", + "value": "1" + }, + { + "name": "PYTHONFAULTHANDLER", + "value": "1" + }, + { + "name": "PYTHONHASHSEED", + "value": "random" + }, + { + "name": "PYTHONUNBUFFERED", + "value": "1" + }, + { + "path": "/root/.local/bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "name": "UV_COMPILE_BYTECODE", + "value": "1" + }, + { + "name": "UV_LINK_MODE", + "value": "copy" + }, + { + "name": "UV_CACHE_DIR", + "value": "/opt/uv-cache" + }, + { + "cmd": "pipx install uv" + }, + { + "dest": "pyproject.toml", + "src": "pyproject.toml" + }, + { + "dest": "uv.lock", + "src": "uv.lock" + }, + { + "cmd": "uv sync --frozen --no-install-project --no-install-workspace --no-dev" + }, + { + "dest": ".", + "src": "." + }, + { + "cmd": "uv sync --frozen --no-dev" + }, + { + "path": "/app/.venv/bin" + } + ], + "dependsOn": [ + "packages:mise", + "setup", + "packages:apt:python-system-deps" + ], + "name": "install" + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y pkg-config'", + "customName": "install apt packages: pkg-config" + } + ], + "name": "packages:apt:python-system-deps", + "useSecrets": false + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/secrets - 1] +{ + "baseImage": "debian:stable-slim", + "secrets": [ + "MY_SECRET", + "MY_OTHER_SECRET", + "HELLO_WORLD" + ], + "start": { + "cmd": "./run.sh" + }, + "steps": [ + { + "name": "packages:mise" + }, + { + "commands": [ + { + "name": "NOT_SECRET", + "value": "not secret" + }, + { + "dest": ".", + "src": "." + }, + { + "cmd": "sh -c './run.sh'" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "usesSecrets", + "useSecrets": true + }, + { + "commands": [ + { + "name": "NOT_SECRET", + "value": "not secret" + }, + { + "dest": ".", + "src": "." + }, + { + "cmd": "sh -c './run.sh'" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "defaultsToUsing" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "cmd": "sh -c './run.sh true'" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "doesNotUseSecrets", + "useSecrets": false + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/staticfile-config - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "caddy run --config Caddyfile --adapter caddyfile 2\u003e\u00261", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.caddy]\n version = \"2.9.1\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: caddy" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "assets": { + "Caddyfile": "{\n\tadmin off\n\tpersist_config off\n\tauto_https off\n\n\tlog {\n\t\tformat json\n\t}\n\n\tservers {\n\t\ttrusted_proxies static private_ranges\n\t}\n}\n\n:{$PORT:80} {\n\tlog {\n\t\tformat json\n\t}\n\n\trespond /health 200\n\n# Security headers\n\theader {\n\t\t# Enable cross-site filter (XSS) and tell browsers to block detected attacks\n\t\tX-XSS-Protection \"1; mode=block\"\n\t\t# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type\n\t\tX-Content-Type-Options \"nosniff\"\n\t\t# Keep referrer data off of HTTP connections\n\t\tReferrer-Policy \"strict-origin-when-cross-origin\"\n\t\t# Enable strict Content Security Policy\n\t\tContent-Security-Policy \"default-src 'self'; img-src 'self' data: https: *; style-src 'self' 'unsafe-inline' https: *; script-src 'self' 'unsafe-inline' https: *; font-src 'self' data: https: *; connect-src 'self' https: *; media-src 'self' https: *; object-src 'none'; frame-src 'self' https: *;\"\n\t\t# Remove Server header\n\t\t-Server\n\t}\n\n\troot * hello\n\n\t# Handle static files\n\tfile_server {\n\t\thide .git\n\t\thide .env*\n\t}\n\n\t# Compression with more formats\n\tencode {\n\t\tgzip\n\t\tzstd\n\t}\n\n\t# Try files with HTML extension and handle SPA routing\n\ttry_files {path} {path}.html {path}/index.html /index.html\n\n\t# Handle 404 errors\n\thandle_errors {\n\t\trewrite * /{err.status_code}.html\n\t\tfile_server\n\t}\n}\n" + }, + "commands": [ + { + "name": "Caddyfile", + "path": "Caddyfile" + }, + { + "cmd": "caddy fmt --overwrite Caddyfile" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/staticfile-index - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "caddy run --config Caddyfile --adapter caddyfile 2\u003e\u00261", + "outputs": [ + "." + ] + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.caddy]\n version = \"2.9.1\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: caddy" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "assets": { + "Caddyfile": "{\n\tadmin off\n\tpersist_config off\n\tauto_https off\n\n\tlog {\n\t\tformat json\n\t}\n\n\tservers {\n\t\ttrusted_proxies static private_ranges\n\t}\n}\n\n:{$PORT:80} {\n\tlog {\n\t\tformat json\n\t}\n\n\trespond /health 200\n\n# Security headers\n\theader {\n\t\t# Enable cross-site filter (XSS) and tell browsers to block detected attacks\n\t\tX-XSS-Protection \"1; mode=block\"\n\t\t# Prevent some browsers from MIME-sniffing a response away from the declared Content-Type\n\t\tX-Content-Type-Options \"nosniff\"\n\t\t# Keep referrer data off of HTTP connections\n\t\tReferrer-Policy \"strict-origin-when-cross-origin\"\n\t\t# Enable strict Content Security Policy\n\t\tContent-Security-Policy \"default-src 'self'; img-src 'self' data: https: *; style-src 'self' 'unsafe-inline' https: *; script-src 'self' 'unsafe-inline' https: *; font-src 'self' data: https: *; connect-src 'self' https: *; media-src 'self' https: *; object-src 'none'; frame-src 'self' https: *;\"\n\t\t# Remove Server header\n\t\t-Server\n\t}\n\n\troot * .\n\n\t# Handle static files\n\tfile_server {\n\t\thide .git\n\t\thide .env*\n\t}\n\n\t# Compression with more formats\n\tencode {\n\t\tgzip\n\t\tzstd\n\t}\n\n\t# Try files with HTML extension and handle SPA routing\n\ttry_files {path} {path}.html {path}/index.html /index.html\n\n\t# Handle 404 errors\n\thandle_errors {\n\t\trewrite * /{err.status_code}.html\n\t\tfile_server\n\t}\n}\n" + }, + "commands": [ + { + "name": "Caddyfile", + "path": "Caddyfile" + }, + { + "cmd": "caddy fmt --overwrite Caddyfile" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/mise-config - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "npm-install": { + "directory": "/root/.npm", + "type": "shared" + } + }, + "start": { + "cmd": "npm run start", + "outputs": [ + "." + ], + "variables": { + "CI": "true", + "NODE_ENV": "production", + "NPM_CONFIG_PRODUCTION": "false", + "YARN_PRODUCTION": "false" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"22.13.1\"\n [tools.npm]\n version = \"11.1.0\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "dest": "/app/mise.toml", + "src": "mise.toml" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, npm" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise", + "/app/mise.toml" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "caches": [ + "npm-install" + ], + "cmd": "npm install" + } + ], + "dependsOn": [ + "packages:mise", + "setup" + ], + "name": "install" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "cmd": "npm run build" + } + ], + "dependsOn": [ + "install" + ], + "name": "build" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/node-npm - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "npm-install": { + "directory": "/root/.npm", + "type": "shared" + } + }, + "start": { + "cmd": "npm run start", + "outputs": [ + "." + ], + "variables": { + "CI": "true", + "NODE_ENV": "production", + "NPM_CONFIG_PRODUCTION": "false", + "YARN_PRODUCTION": "false" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"23.5.0\"\n [tools.npm]\n version = \"9.9.4\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, npm" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "dest": "package-lock.json", + "src": "package-lock.json" + }, + { + "caches": [ + "npm-install" + ], + "cmd": "npm ci" + } + ], + "dependsOn": [ + "packages:mise", + "setup" + ], + "name": "install" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/node-npm-workspaces - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "npm-install": { + "directory": "/root/.npm", + "type": "shared" + } + }, + "start": { + "cmd": "node index.js", + "outputs": [ + "." + ], + "variables": { + "CI": "true", + "NODE_ENV": "production", + "NPM_CONFIG_PRODUCTION": "false", + "YARN_PRODUCTION": "false" + } + }, + "steps": [ + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"9.9.4\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, npm" + } + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "dest": "packages/pkg-a/package.json", + "src": "packages/pkg-a/package.json" + }, + { + "dest": "packages/pkg-b/package.json", + "src": "packages/pkg-b/package.json" + }, + { + "dest": "package-lock.json", + "src": "package-lock.json" + }, + { + "caches": [ + "npm-install" + ], + "cmd": "npm ci" + } + ], + "dependsOn": [ + "packages:mise", + "setup" + ], + "name": "install" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/php-laravel-inertia - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + }, + "npm-install": { + "directory": "/root/.npm", + "type": "shared" + } + }, + "start": { + "cmd": "bash /start-nginx.sh", + "outputs": [ + "." + ] + }, + "steps": [ + { + "name": "packages:image", + "startingImage": "php:8.2.27-fpm", + "useSecrets": false + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y git nginx unzip zip'", + "customName": "install apt packages: git nginx unzip zip" + } + ], + "dependsOn": [ + "packages:image" + ], + "name": "packages:apt:nginx", + "useSecrets": false + }, + { + "commands": [ + { + "dest": "/usr/bin/composer", + "image": "composer:latest", + "src": "/usr/bin/composer" + }, + { + "dest": ".", + "src": "." + }, + { + "cmd": "composer install --ignore-platform-reqs" + } + ], + "dependsOn": [ + "packages:apt:nginx" + ], + "name": "install" + }, + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"9.9.4\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, npm" + } + ], + "dependsOn": [ + "packages:image" + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup:node" + }, + { + "commands": [ + { + "dest": "package.json", + "src": "package.json" + }, + { + "dest": "package-lock.json", + "src": "package-lock.json" + }, + { + "caches": [ + "npm-install" + ], + "cmd": "npm ci" + } + ], + "dependsOn": [ + "packages:mise", + "setup:node" + ], + "name": "install:node" + }, + { + "commands": [ + { + "dest": ".", + "src": "." + }, + { + "cmd": "npm run build" + } + ], + "dependsOn": [ + "install:node" + ], + "name": "build:node" + }, + { + "assets": { + "nginx.conf": "worker_processes 5;\ndaemon off;\n\nworker_rlimit_nofile 8192;\n\nevents {\n worker_connections 4096;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n index index.html index.htm index.php;\n\n default_type application/octet-stream;\n log_format main '$remote_addr - $remote_user [$time_local] $status '\n '\"$request\" $body_bytes_sent \"$http_referer\" '\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n access_log /dev/stdout;\n error_log /dev/stdout;\n sendfile on;\n tcp_nopush on;\n server_names_hash_bucket_size 128; # this seems to be required for some vhosts\n\n server {\n listen 0.0.0.0:80;\n listen [::]:80;\n\n server_name localhost;\n\n \n root /app/public;\n \n \n add_header X-Frame-Options \"SAMEORIGIN\";\n add_header X-Content-Type-Options \"nosniff\";\n \n index index.php;\n \n charset utf-8;\n \n \n location / {\n try_files $uri $uri/ /index.php?$query_string;\n }\n \n \n \n \n location = /favicon.ico { access_log off; log_not_found off; }\n location = /robots.txt { access_log off; log_not_found off; }\n \n \n error_page 404 /index.php;\n \n \n location ~ \\.php$ {\n fastcgi_pass 127.0.0.1:9000;\n fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;\n include /etc/nginx/fastcgi_params;\n include /etc/nginx/fastcgi.conf;\n }\n \n location ~ /\\.(?!well-known).* {\n deny all;\n }\n }\n}\n", + "php-fpm.conf": "[www]\nlisten = 127.0.0.1:9000\nuser = nobody\npm = dynamic\npm.max_children = 50\npm.min_spare_servers = 4\npm.max_spare_servers = 32\npm.start_servers = 18\nclear_env = no\ncatch_workers_output = yes\n", + "start-nginx.sh": "#!/bin/bash\n\nset -e\n\nPORT=${PORT:-80}\n\n# Set the port in the nginx config\nsed -i \"s/80/$PORT/g\" /etc/nginx/railpack.conf\n\n# Set the storage permissions for Laravel\nif [ \"$IS_LARAVEL\" = \"true\" ]; then\n chmod -R ugo+rw /app/storage\nfi\n\necho \"Starting Nginx on port $PORT\"\n\n# Start php-fpm and nginx\nphp-fpm --fpm-config /etc/php-fpm.conf \u0026 nginx -c /etc/nginx/railpack.conf\n" + }, + "commands": [ + { + "customName": "create nginx config", + "name": "nginx.conf", + "path": "/etc/nginx/railpack.conf" + }, + { + "cmd": "nginx -t -c /etc/nginx/railpack.conf" + }, + { + "customName": "create php-fpm config", + "name": "php-fpm.conf", + "path": "/etc/php-fpm.conf" + }, + { + "customName": "create start nginx script", + "mode": 493, + "name": "start-nginx.sh", + "path": "/start-nginx.sh" + }, + { + "name": "IS_LARAVEL", + "value": "true" + } + ], + "dependsOn": [ + "packages:apt:nginx" + ], + "name": "nginx:setup" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/php-vanilla - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "bash /start-nginx.sh", + "outputs": [ + "." + ] + }, + "steps": [ + { + "name": "packages:image", + "startingImage": "php:8.4.3-fpm", + "useSecrets": false + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y git nginx unzip zip'", + "customName": "install apt packages: git nginx unzip zip" + } + ], + "dependsOn": [ + "packages:image" + ], + "name": "packages:apt:nginx", + "useSecrets": false + }, + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"11.1.0\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, npm" + } + ], + "dependsOn": [ + "packages:image" + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup:node" + }, + { + "assets": { + "nginx.conf": "worker_processes 5;\ndaemon off;\n\nworker_rlimit_nofile 8192;\n\nevents {\n worker_connections 4096;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n index index.html index.htm index.php;\n\n default_type application/octet-stream;\n log_format main '$remote_addr - $remote_user [$time_local] $status '\n '\"$request\" $body_bytes_sent \"$http_referer\" '\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n access_log /dev/stdout;\n error_log /dev/stdout;\n sendfile on;\n tcp_nopush on;\n server_names_hash_bucket_size 128; # this seems to be required for some vhosts\n\n server {\n listen 0.0.0.0:80;\n listen [::]:80;\n\n server_name localhost;\n\n \n root /app;\n \n \n add_header X-Frame-Options \"SAMEORIGIN\";\n add_header X-Content-Type-Options \"nosniff\";\n \n index index.php;\n \n charset utf-8;\n \n \n \n \n \n location = /favicon.ico { access_log off; log_not_found off; }\n location = /robots.txt { access_log off; log_not_found off; }\n \n \n \n location ~ \\.php$ {\n fastcgi_pass 127.0.0.1:9000;\n fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;\n include /etc/nginx/fastcgi_params;\n include /etc/nginx/fastcgi.conf;\n }\n \n location ~ /\\.(?!well-known).* {\n deny all;\n }\n }\n}\n", + "php-fpm.conf": "[www]\nlisten = 127.0.0.1:9000\nuser = nobody\npm = dynamic\npm.max_children = 50\npm.min_spare_servers = 4\npm.max_spare_servers = 32\npm.start_servers = 18\nclear_env = no\ncatch_workers_output = yes\n", + "start-nginx.sh": "#!/bin/bash\n\nset -e\n\nPORT=${PORT:-80}\n\n# Set the port in the nginx config\nsed -i \"s/80/$PORT/g\" /etc/nginx/railpack.conf\n\n# Set the storage permissions for Laravel\nif [ \"$IS_LARAVEL\" = \"true\" ]; then\n chmod -R ugo+rw /app/storage\nfi\n\necho \"Starting Nginx on port $PORT\"\n\n# Start php-fpm and nginx\nphp-fpm --fpm-config /etc/php-fpm.conf \u0026 nginx -c /etc/nginx/railpack.conf\n" + }, + "commands": [ + { + "customName": "create nginx config", + "name": "nginx.conf", + "path": "/etc/nginx/railpack.conf" + }, + { + "cmd": "nginx -t -c /etc/nginx/railpack.conf" + }, + { + "customName": "create php-fpm config", + "name": "php-fpm.conf", + "path": "/etc/php-fpm.conf" + }, + { + "customName": "create start nginx script", + "mode": 493, + "name": "start-nginx.sh", + "path": "/start-nginx.sh" + } + ], + "dependsOn": [ + "packages:apt:nginx" + ], + "name": "nginx:setup" + } + ] +} +--- + +[TestGenerateBuildPlanForExamples/php-vanilla-82 - 1] +{ + "baseImage": "debian:stable-slim", + "caches": { + "apt": { + "directory": "/var/cache/apt", + "type": "locked" + }, + "apt-lists": { + "directory": "/var/lib/apt/lists", + "type": "locked" + }, + "mise": { + "directory": "/mise/cache", + "type": "shared" + } + }, + "start": { + "cmd": "bash /start-nginx.sh", + "outputs": [ + "." + ] + }, + "steps": [ + { + "name": "packages:image", + "startingImage": "php:8.2.27-fpm", + "useSecrets": false + }, + { + "commands": [ + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y git nginx unzip zip'", + "customName": "install apt packages: git nginx unzip zip" + } + ], + "dependsOn": [ + "packages:image" + ], + "name": "packages:apt:nginx", + "useSecrets": false + }, + { + "commands": [ + { + "dest": "/usr/bin/composer", + "image": "composer:latest", + "src": "/usr/bin/composer" + }, + { + "dest": ".", + "src": "." + }, + { + "cmd": "composer install --ignore-platform-reqs" + } + ], + "dependsOn": [ + "packages:apt:nginx" + ], + "name": "install" + }, + { + "assets": { + "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"11.1.0\"\n" + }, + "commands": [ + { + "name": "MISE_DATA_DIR", + "value": "/mise" + }, + { + "name": "MISE_CONFIG_DIR", + "value": "/mise" + }, + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, + { + "name": "MISE_CACHE_DIR", + "value": "/mise/cache" + }, + { + "path": "/mise/shims" + }, + { + "caches": [ + "apt", + "apt-lists" + ], + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'curl -fsSL https://mise.run | sh'", + "customName": "install mise" + }, + { + "customName": "create mise config", + "name": "mise.toml", + "path": "/etc/mise/config.toml" + }, + { + "caches": [ + "mise" + ], + "cmd": "sh -c 'mise trust -a \u0026\u0026 mise install'", + "customName": "install mise packages: node, npm" + } + ], + "dependsOn": [ + "packages:image" + ], + "name": "packages:mise", + "outputs": [ + "/mise/shims", + "/mise/installs", + "/usr/local/bin/mise", + "/etc/mise/config.toml", + "/root/.local/state/mise" + ], + "useSecrets": false + }, + { + "commands": [ + { + "name": "CI", + "value": "true" + }, + { + "name": "NODE_ENV", + "value": "production" + }, + { + "name": "NPM_CONFIG_PRODUCTION", + "value": "false" + }, + { + "name": "YARN_PRODUCTION", + "value": "false" + }, + { + "path": "/app/node_modules/.bin" + } + ], + "dependsOn": [ + "packages:mise" + ], + "name": "setup:node" + }, + { + "assets": { + "nginx.conf": "worker_processes 5;\ndaemon off;\n\nworker_rlimit_nofile 8192;\n\nevents {\n worker_connections 4096;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n index index.html index.htm index.php;\n\n default_type application/octet-stream;\n log_format main '$remote_addr - $remote_user [$time_local] $status '\n '\"$request\" $body_bytes_sent \"$http_referer\" '\n '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n access_log /dev/stdout;\n error_log /dev/stdout;\n sendfile on;\n tcp_nopush on;\n server_names_hash_bucket_size 128; # this seems to be required for some vhosts\n\n server {\n listen 0.0.0.0:80;\n listen [::]:80;\n\n server_name localhost;\n\n \n root /app;\n \n \n add_header X-Frame-Options \"SAMEORIGIN\";\n add_header X-Content-Type-Options \"nosniff\";\n \n index index.php;\n \n charset utf-8;\n \n \n \n \n \n location = /favicon.ico { access_log off; log_not_found off; }\n location = /robots.txt { access_log off; log_not_found off; }\n \n \n \n location ~ \\.php$ {\n fastcgi_pass 127.0.0.1:9000;\n fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;\n include /etc/nginx/fastcgi_params;\n include /etc/nginx/fastcgi.conf;\n }\n \n location ~ /\\.(?!well-known).* {\n deny all;\n }\n }\n}\n", + "php-fpm.conf": "[www]\nlisten = 127.0.0.1:9000\nuser = nobody\npm = dynamic\npm.max_children = 50\npm.min_spare_servers = 4\npm.max_spare_servers = 32\npm.start_servers = 18\nclear_env = no\ncatch_workers_output = yes\n", + "start-nginx.sh": "#!/bin/bash\n\nset -e\n\nPORT=${PORT:-80}\n\n# Set the port in the nginx config\nsed -i \"s/80/$PORT/g\" /etc/nginx/railpack.conf\n\n# Set the storage permissions for Laravel\nif [ \"$IS_LARAVEL\" = \"true\" ]; then\n chmod -R ugo+rw /app/storage\nfi\n\necho \"Starting Nginx on port $PORT\"\n\n# Start php-fpm and nginx\nphp-fpm --fpm-config /etc/php-fpm.conf \u0026 nginx -c /etc/nginx/railpack.conf\n" + }, + "commands": [ + { + "customName": "create nginx config", + "name": "nginx.conf", + "path": "/etc/nginx/railpack.conf" + }, + { + "cmd": "nginx -t -c /etc/nginx/railpack.conf" + }, + { + "customName": "create php-fpm config", + "name": "php-fpm.conf", + "path": "/etc/php-fpm.conf" + }, + { + "customName": "create start nginx script", + "mode": 493, + "name": "start-nginx.sh", + "path": "/start-nginx.sh" + } + ], + "dependsOn": [ + "packages:apt:nginx" + ], + "name": "nginx:setup" + } + ] +} +--- diff --git a/core/core_test.go b/core/core_test.go new file mode 100644 index 0000000..bc6a8c4 --- /dev/null +++ b/core/core_test.go @@ -0,0 +1,44 @@ +package core + +import ( + "os" + "path/filepath" + "testing" + + "github.com/gkampitakis/go-snaps/snaps" + "github.com/railwayapp/railpack/core/app" + "github.com/stretchr/testify/require" +) + +func TestGenerateBuildPlanForExamples(t *testing.T) { + wd, err := os.Getwd() + require.NoError(t, err) + + // Get all the examples + examplesDir := filepath.Join(filepath.Dir(wd), "examples") + entries, err := os.ReadDir(examplesDir) + require.NoError(t, err) + + for _, entry := range entries { + if !entry.IsDir() { + continue + } + + // For each example, generate a build plan that we can snapshot test + t.Run(entry.Name(), func(t *testing.T) { + examplePath := filepath.Join(examplesDir, entry.Name()) + + userApp, err := app.NewApp(examplePath) + require.NoError(t, err) + + env := app.NewEnvironment(nil) + + buildResult, err := GenerateBuildPlan(userApp, env, &GenerateBuildPlanOptions{}) + require.NoError(t, err) + + plan := buildResult.Plan + + snaps.MatchJSON(t, plan) + }) + } +} diff --git a/core/generate/__snapshots__/context_test.snap b/core/generate/__snapshots__/context_test.snap index d2dde19..1ad850f 100755 --- a/core/generate/__snapshots__/context_test.snap +++ b/core/generate/__snapshots__/context_test.snap @@ -56,8 +56,8 @@ "apt", "apt-lists" ], - "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl'", - "customName": "install apt packages: ca-certificates curl" + "cmd": "sh -c 'apt-get update \u0026\u0026 apt-get install -y ca-certificates curl git'", + "customName": "install apt packages: ca-certificates curl git" }, { "caches": [ diff --git a/core/generate/command_step_builder.go b/core/generate/command_step_builder.go index c369aa1..bb5f3b5 100644 --- a/core/generate/command_step_builder.go +++ b/core/generate/command_step_builder.go @@ -1,6 +1,9 @@ package generate import ( + "maps" + "slices" + "github.com/railwayapp/railpack/core/plan" "github.com/railwayapp/railpack/core/utils" ) @@ -47,8 +50,9 @@ func (b *CommandStepBuilder) AddCommands(commands []plan.Command) { func (b *CommandStepBuilder) AddEnvVars(envVars map[string]string) { commands := []plan.Command{} - for k, v := range envVars { - commands = append(commands, plan.NewVariableCommand(k, v)) + + for _, k := range slices.Sorted(maps.Keys(envVars)) { + commands = append(commands, plan.NewVariableCommand(k, envVars[k])) } b.AddCommands(commands) } diff --git a/core/generate/context.go b/core/generate/context.go index 51c8056..a285882 100644 --- a/core/generate/context.go +++ b/core/generate/context.go @@ -2,6 +2,8 @@ package generate import ( "fmt" + "maps" + "slices" "sort" "strings" @@ -149,7 +151,8 @@ func (c *GenerateContext) Generate() (*plan.BuildPlan, map[string]*resolver.Reso func (c *GenerateContext) ApplyConfig(config *config.Config) error { // Mise package config miseStep := c.GetMiseStepBuilder() - for pkg, version := range config.Packages { + for _, pkg := range slices.Sorted(maps.Keys(config.Packages)) { + version := config.Packages[pkg] pkgRef := miseStep.Default(pkg, version) miseStep.Version(pkgRef, version, "custom config") } diff --git a/core/generate/context_test.go b/core/generate/context_test.go index 5f3b8a2..32e3ddb 100644 --- a/core/generate/context_test.go +++ b/core/generate/context_test.go @@ -62,8 +62,8 @@ func TestGenerateContext(t *testing.T) { configJSON := `{ "packages": { "node": "20", - "go": "1.23", - "python": "3.13" + "go": "1.23.5", + "python": "3.13.1" }, "aptPackages": ["curl"], "steps": { diff --git a/core/mise/mise.go b/core/mise/mise.go index b5e8425..88e106e 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -58,8 +58,9 @@ func (m *Mise) runCmd(args ...string) (string, error) { // I am testing out forcing usage of the git CLI to see if it helps // Source: https://github.com/jdx/mise/blob/main/src/git.rs#L124 // Config: https://github.com/jdx/mise/blob/main/settings.toml#L369 - cmd.Env = append(cmd.Env, "MISE_LIBGIT2=false") + // cmd.Env = append(cmd.Env, "MISE_LIBGIT2=false") cmd.Env = append(cmd.Env, "MISE_GIX=false") + // cmd.Env = append(cmd.Env, "RUST_BACKTRACE=full") if err := cmd.Run(); err != nil { return "", fmt.Errorf("failed to run mise command '%s': %w\nstdout: %s\nstderr: %s", From 978d5344bad6b2f8487362a48aa4e32a460ac687 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 15:46:57 -0800 Subject: [PATCH 02/11] update --- core/__snapshots__/core_test.snap | 28 ++++++++++++++-------------- core/generate/context.go | 4 +++- core/mise/mise.go | 2 +- core/providers/python/python.go | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/core/__snapshots__/core_test.snap b/core/__snapshots__/core_test.snap index 049777e..3d6960b 100755 --- a/core/__snapshots__/core_test.snap +++ b/core/__snapshots__/core_test.snap @@ -961,7 +961,7 @@ "steps": [ { "assets": { - "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.2\"\n" + "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ { @@ -1143,7 +1143,7 @@ "steps": [ { "assets": { - "mise.toml": "[tools]\n [tools.python]\n version = \"3.13.2\"\n" + "mise.toml": "[tools]\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ { @@ -1306,7 +1306,7 @@ "steps": [ { "assets": { - "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.2\"\n" + "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ { @@ -1848,43 +1848,43 @@ "dependsOn": [ "packages:mise" ], - "name": "usesSecrets", - "useSecrets": true + "name": "defaultsToUsing" }, { "commands": [ - { - "name": "NOT_SECRET", - "value": "not secret" - }, { "dest": ".", "src": "." }, { - "cmd": "sh -c './run.sh'" + "cmd": "sh -c './run.sh true'" } ], "dependsOn": [ "packages:mise" ], - "name": "defaultsToUsing" + "name": "doesNotUseSecrets", + "useSecrets": false }, { "commands": [ + { + "name": "NOT_SECRET", + "value": "not secret" + }, { "dest": ".", "src": "." }, { - "cmd": "sh -c './run.sh true'" + "cmd": "sh -c './run.sh'" } ], "dependsOn": [ "packages:mise" ], - "name": "doesNotUseSecrets", - "useSecrets": false + "name": "usesSecrets", + "useSecrets": true } ] } diff --git a/core/generate/context.go b/core/generate/context.go index a285882..b9850cc 100644 --- a/core/generate/context.go +++ b/core/generate/context.go @@ -167,7 +167,9 @@ func (c *GenerateContext) ApplyConfig(config *config.Config) error { } // Step config - for name, configStep := range config.Steps { + for _, name := range slices.Sorted(maps.Keys(config.Steps)) { + configStep := config.Steps[name] + var commandStepBuilder *CommandStepBuilder // We need to use the key as the step name and not `configStep.Name` diff --git a/core/mise/mise.go b/core/mise/mise.go index 88e106e..834650c 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -59,7 +59,7 @@ func (m *Mise) runCmd(args ...string) (string, error) { // Source: https://github.com/jdx/mise/blob/main/src/git.rs#L124 // Config: https://github.com/jdx/mise/blob/main/settings.toml#L369 // cmd.Env = append(cmd.Env, "MISE_LIBGIT2=false") - cmd.Env = append(cmd.Env, "MISE_GIX=false") + // cmd.Env = append(cmd.Env, "MISE_GIX=false") // cmd.Env = append(cmd.Env, "RUST_BACKTRACE=full") if err := cmd.Run(); err != nil { diff --git a/core/providers/python/python.go b/core/providers/python/python.go index 2dce083..542738f 100644 --- a/core/providers/python/python.go +++ b/core/providers/python/python.go @@ -9,7 +9,7 @@ import ( ) const ( - DEFAULT_PYTHON_VERSION = "3.13" + DEFAULT_PYTHON_VERSION = "3.13.1" UV_CACHE_DIR = "/opt/uv-cache" PIP_CACHE_DIR = "/opt/pip-cache" ) From 73c810d45fb61be0a2ab493260f728383dd0e89f Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:31:54 -0800 Subject: [PATCH 03/11] append the system path to mise command --- core/__snapshots__/core_test.snap | 152 +++++++++--------- core/generate/__snapshots__/context_test.snap | 8 +- core/generate/context.go | 2 +- core/generate/mise_step_builder.go | 2 +- core/mise/mise.go | 24 +++ go.mod | 1 + go.sum | 5 + 7 files changed, 112 insertions(+), 82 deletions(-) diff --git a/core/__snapshots__/core_test.snap b/core/__snapshots__/core_test.snap index 3d6960b..ef5952c 100755 --- a/core/__snapshots__/core_test.snap +++ b/core/__snapshots__/core_test.snap @@ -28,6 +28,10 @@ "mise.toml": "[tools]\n [tools.python]\n version = \"3.13.2\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -36,10 +40,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -216,6 +216,10 @@ "mise.toml": "[tools]\n [tools.go]\n version = \"1.18\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -224,10 +228,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -356,6 +356,10 @@ "mise.toml": "[tools]\n [tools.go]\n version = \"1.23.6\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -364,10 +368,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -501,6 +501,10 @@ "mise.toml": "[tools]\n [tools.bun]\n version = \"1.2.2\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -509,10 +513,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -666,6 +666,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"20.18.2\"\n [tools.pnpm]\n version = \"10.2.0\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -674,10 +678,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -847,6 +847,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.pnpm]\n version = \"10.2.0\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -855,10 +859,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -964,6 +964,10 @@ "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -972,10 +976,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -1146,6 +1146,10 @@ "mise.toml": "[tools]\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -1154,10 +1158,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -1309,6 +1309,10 @@ "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -1317,10 +1321,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -1483,6 +1483,10 @@ "mise.toml": "[tools]\n [tools.python]\n version = \"3.11.11\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -1491,10 +1495,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -1651,6 +1651,10 @@ "mise.toml": "[tools]\n [tools.pipx]\n version = \"1.7.1\"\n [tools.python]\n version = \"3.11.11\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -1659,10 +1663,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -1919,6 +1919,10 @@ "mise.toml": "[tools]\n [tools.caddy]\n version = \"2.9.1\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -1927,10 +1931,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -2027,6 +2027,10 @@ "mise.toml": "[tools]\n [tools.caddy]\n version = \"2.9.1\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -2035,10 +2039,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -2145,6 +2145,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"22.13.1\"\n [tools.npm]\n version = \"11.1.0\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -2153,10 +2157,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -2311,6 +2311,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"23.5.0\"\n [tools.npm]\n version = \"9.9.4\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -2319,10 +2323,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -2461,6 +2461,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"9.9.4\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -2469,10 +2473,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -2655,6 +2655,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"9.9.4\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -2663,10 +2667,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -2871,6 +2871,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"11.1.0\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -2879,10 +2883,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" @@ -3065,6 +3065,10 @@ "mise.toml": "[tools]\n [tools.node]\n version = \"23.7.0\"\n [tools.npm]\n version = \"11.1.0\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -3073,10 +3077,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" diff --git a/core/generate/__snapshots__/context_test.snap b/core/generate/__snapshots__/context_test.snap index 1ad850f..2e80c94 100755 --- a/core/generate/__snapshots__/context_test.snap +++ b/core/generate/__snapshots__/context_test.snap @@ -32,6 +32,10 @@ "mise.toml": "[tools]\n [tools.go]\n version = \"1.23.5\"\n [tools.node]\n version = \"20.18.2\"\n [tools.python]\n version = \"3.13.1\"\n" }, "commands": [ + { + "name": "MISE_INSTALL_PATH", + "value": "/usr/local/bin/mise" + }, { "name": "MISE_DATA_DIR", "value": "/mise" @@ -40,10 +44,6 @@ "name": "MISE_CONFIG_DIR", "value": "/mise" }, - { - "name": "MISE_INSTALL_PATH", - "value": "/usr/local/bin/mise" - }, { "name": "MISE_CACHE_DIR", "value": "/mise/cache" diff --git a/core/generate/context.go b/core/generate/context.go index b9850cc..42c87d8 100644 --- a/core/generate/context.go +++ b/core/generate/context.go @@ -51,7 +51,7 @@ type GenerateContext struct { } func NewGenerateContext(app *a.App, env *a.Environment) (*GenerateContext, error) { - resolver, err := resolver.NewResolver(mise.TestInstallDir) + resolver, err := resolver.NewResolver(mise.InstallDir) if err != nil { return nil, err } diff --git a/core/generate/mise_step_builder.go b/core/generate/mise_step_builder.go index 8bc3dc7..28c6934 100644 --- a/core/generate/mise_step_builder.go +++ b/core/generate/mise_step_builder.go @@ -84,9 +84,9 @@ func (b *MiseStepBuilder) Build(options *BuildStepOptions) (*plan.Step, error) { // Install mise step.AddCommands([]plan.Command{ + plan.NewVariableCommand("MISE_INSTALL_PATH", "/usr/local/bin/mise"), plan.NewVariableCommand("MISE_DATA_DIR", "/mise"), plan.NewVariableCommand("MISE_CONFIG_DIR", "/mise"), - plan.NewVariableCommand("MISE_INSTALL_PATH", "/usr/local/bin/mise"), plan.NewVariableCommand("MISE_CACHE_DIR", "/mise/cache"), plan.NewPathCommand("/mise/shims"), options.NewAptInstallCommand([]string{"curl", "ca-certificates", "git"}), diff --git a/core/mise/mise.go b/core/mise/mise.go index 834650c..966f479 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -3,7 +3,9 @@ package mise import ( "bytes" "fmt" + "os" "os/exec" + "path/filepath" "strings" "github.com/BurntSushi/toml" @@ -16,6 +18,7 @@ const ( type Mise struct { binaryPath string + cacheDir string } func New(cacheDir string) (*Mise, error) { @@ -26,6 +29,7 @@ func New(cacheDir string) (*Mise, error) { return &Mise{ binaryPath: binaryPath, + cacheDir: cacheDir, }, nil } @@ -47,6 +51,18 @@ func (m *Mise) GetLatestVersion(pkg, version string) (string, error) { // runCmd runs a mise command with the given arguments func (m *Mise) runCmd(args ...string) (string, error) { + // Use persistent directories for mise data and cache + cacheDir := filepath.Join(m.cacheDir, "cache") + dataDir := filepath.Join(m.cacheDir, "data") + + // mu, err := filemutex.New("/tmp/foo.lock") + // if err != nil { + // return "", fmt.Errorf("failed to create mutex: %w", err) + // } + + // mu.Lock() // Will block until lock can be acquired + // defer mu.Unlock() + cmd := exec.Command(m.binaryPath, args...) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout @@ -62,6 +78,14 @@ func (m *Mise) runCmd(args ...string) (string, error) { // cmd.Env = append(cmd.Env, "MISE_GIX=false") // cmd.Env = append(cmd.Env, "RUST_BACKTRACE=full") + cmd.Env = append(cmd.Env, + fmt.Sprintf("MISE_CACHE_DIR=%s", cacheDir), + fmt.Sprintf("MISE_DATA_DIR=%s", dataDir), + fmt.Sprintf("PATH=%s", os.Getenv("PATH")), + ) + + // cmd.Env = append(cmd.Env, os.Environ()...) + if err := cmd.Run(); err != nil { return "", fmt.Errorf("failed to run mise command '%s': %w\nstdout: %s\nstderr: %s", strings.Join(append([]string{m.binaryPath}, args...), " "), diff --git a/go.mod b/go.mod index 219758c..a58b454 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/alexflint/go-filemutex v1.3.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect diff --git a/go.sum b/go.sum index fc1cdc4..2d4ef12 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= +github.com/alexflint/go-filemutex v1.3.0 h1:LgE+nTUWnQCyRKbpoceKZsPQbs84LivvgwUymZXdOcM= +github.com/alexflint/go-filemutex v1.3.0/go.mod h1:U0+VA/i30mGBlLCrFPGtTe9y6wGQfNAWPBTekHQ+c8A= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc= github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -195,6 +197,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -274,6 +277,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= @@ -303,6 +307,7 @@ google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 2c1af48c977c18cf1ff2aff05193e6ca3778959d Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:35:36 -0800 Subject: [PATCH 04/11] no gix --- core/mise/mise.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/mise/mise.go b/core/mise/mise.go index 966f479..2033139 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -82,6 +82,7 @@ func (m *Mise) runCmd(args ...string) (string, error) { fmt.Sprintf("MISE_CACHE_DIR=%s", cacheDir), fmt.Sprintf("MISE_DATA_DIR=%s", dataDir), fmt.Sprintf("PATH=%s", os.Getenv("PATH")), + "MISE_GIX=false", ) // cmd.Env = append(cmd.Env, os.Environ()...) From 23dcb3152ecde44a72aba0699f27e63731110a89 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:37:43 -0800 Subject: [PATCH 05/11] update lint step name --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b2b3e3..64588e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: go-version: "1.23.4" cache: true - - name: Install golangci-lint + - name: Lint uses: golangci/golangci-lint-action@v6 with: version: v1.63.4 From 2232be4f5d6be5588f9ac390050161159bffceee Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:38:10 -0800 Subject: [PATCH 06/11] no libgit2 --- core/mise/mise.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/mise/mise.go b/core/mise/mise.go index 2033139..9467da9 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -83,6 +83,7 @@ func (m *Mise) runCmd(args ...string) (string, error) { fmt.Sprintf("MISE_DATA_DIR=%s", dataDir), fmt.Sprintf("PATH=%s", os.Getenv("PATH")), "MISE_GIX=false", + "MISE_LIBGIT2=false", ) // cmd.Env = append(cmd.Env, os.Environ()...) From 9bef1a6282cee2536759850221e528f41fd86323 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:43:15 -0800 Subject: [PATCH 07/11] comments --- core/mise/mise.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/mise/mise.go b/core/mise/mise.go index 9467da9..0b0e737 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -68,12 +68,6 @@ func (m *Mise) runCmd(args ...string) (string, error) { cmd.Stdout = &stdout cmd.Stderr = &stderr - // We want to shell out to the git CLI here - // Without it, I was noticing races when multiple processes tried to check the version of the same package in parallel - // Sometimes a checkout operation would fail. - // I am testing out forcing usage of the git CLI to see if it helps - // Source: https://github.com/jdx/mise/blob/main/src/git.rs#L124 - // Config: https://github.com/jdx/mise/blob/main/settings.toml#L369 // cmd.Env = append(cmd.Env, "MISE_LIBGIT2=false") // cmd.Env = append(cmd.Env, "MISE_GIX=false") // cmd.Env = append(cmd.Env, "RUST_BACKTRACE=full") @@ -82,6 +76,13 @@ func (m *Mise) runCmd(args ...string) (string, error) { fmt.Sprintf("MISE_CACHE_DIR=%s", cacheDir), fmt.Sprintf("MISE_DATA_DIR=%s", dataDir), fmt.Sprintf("PATH=%s", os.Getenv("PATH")), + + // We want to shell out to the git CLI here + // Without it, I was noticing races when multiple processes tried to check the version of the same package in parallel + // Sometimes a checkout operation would fail. + // I am testing out forcing usage of the git CLI to see if it helps + // Source: https://github.com/jdx/mise/blob/main/src/git.rs#L124 + // Config: https://github.com/jdx/mise/blob/main/settings.toml#L369 "MISE_GIX=false", "MISE_LIBGIT2=false", ) From 18deeccde79b5a945198be0c08e925d29f1942d7 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:44:35 -0800 Subject: [PATCH 08/11] use a file mutex --- core/mise/mise.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/core/mise/mise.go b/core/mise/mise.go index 0b0e737..d88eaa7 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/BurntSushi/toml" + "github.com/alexflint/go-filemutex" ) const ( @@ -55,13 +56,13 @@ func (m *Mise) runCmd(args ...string) (string, error) { cacheDir := filepath.Join(m.cacheDir, "cache") dataDir := filepath.Join(m.cacheDir, "data") - // mu, err := filemutex.New("/tmp/foo.lock") - // if err != nil { - // return "", fmt.Errorf("failed to create mutex: %w", err) - // } + mu, err := filemutex.New("/tmp/foo.lock") + if err != nil { + return "", fmt.Errorf("failed to create mutex: %w", err) + } - // mu.Lock() // Will block until lock can be acquired - // defer mu.Unlock() + mu.Lock() // Will block until lock can be acquired + defer mu.Unlock() cmd := exec.Command(m.binaryPath, args...) var stdout, stderr bytes.Buffer From 1a6bfddff7b44d2f9c4a8e1f4474dc0bbddae2cd Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:46:12 -0800 Subject: [PATCH 09/11] check return of file mutex --- core/mise/mise.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/mise/mise.go b/core/mise/mise.go index d88eaa7..0ee71a2 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -10,6 +10,7 @@ import ( "github.com/BurntSushi/toml" "github.com/alexflint/go-filemutex" + "github.com/charmbracelet/log" ) const ( @@ -61,8 +62,14 @@ func (m *Mise) runCmd(args ...string) (string, error) { return "", fmt.Errorf("failed to create mutex: %w", err) } - mu.Lock() // Will block until lock can be acquired - defer mu.Unlock() + if err := mu.Lock(); err != nil { + return "", fmt.Errorf("failed to acquire lock: %w", err) + } + defer func() { + if err := mu.Unlock(); err != nil { + log.Printf("failed to release lock: %v", err) + } + }() cmd := exec.Command(m.binaryPath, args...) var stdout, stderr bytes.Buffer From f51b9346a2ad9205ad7b92e2c7ca7ced05d3dcb6 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:47:50 -0800 Subject: [PATCH 10/11] better file lock location --- core/mise/mise.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/core/mise/mise.go b/core/mise/mise.go index 0ee71a2..b14b44d 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -53,11 +53,11 @@ func (m *Mise) GetLatestVersion(pkg, version string) (string, error) { // runCmd runs a mise command with the given arguments func (m *Mise) runCmd(args ...string) (string, error) { - // Use persistent directories for mise data and cache cacheDir := filepath.Join(m.cacheDir, "cache") dataDir := filepath.Join(m.cacheDir, "data") + fileLockPath := filepath.Join(m.cacheDir, "lock") - mu, err := filemutex.New("/tmp/foo.lock") + mu, err := filemutex.New(fileLockPath) if err != nil { return "", fmt.Errorf("failed to create mutex: %w", err) } @@ -76,10 +76,6 @@ func (m *Mise) runCmd(args ...string) (string, error) { cmd.Stdout = &stdout cmd.Stderr = &stderr - // cmd.Env = append(cmd.Env, "MISE_LIBGIT2=false") - // cmd.Env = append(cmd.Env, "MISE_GIX=false") - // cmd.Env = append(cmd.Env, "RUST_BACKTRACE=full") - cmd.Env = append(cmd.Env, fmt.Sprintf("MISE_CACHE_DIR=%s", cacheDir), fmt.Sprintf("MISE_DATA_DIR=%s", dataDir), @@ -91,8 +87,8 @@ func (m *Mise) runCmd(args ...string) (string, error) { // I am testing out forcing usage of the git CLI to see if it helps // Source: https://github.com/jdx/mise/blob/main/src/git.rs#L124 // Config: https://github.com/jdx/mise/blob/main/settings.toml#L369 - "MISE_GIX=false", - "MISE_LIBGIT2=false", + // "MISE_GIX=false", + // "MISE_LIBGIT2=false", ) // cmd.Env = append(cmd.Env, os.Environ()...) From 14b46777c1880e8aff05b20273caed0eb3394c30 Mon Sep 17 00:00:00 2001 From: Jake Runzer Date: Wed, 5 Feb 2025 16:52:43 -0800 Subject: [PATCH 11/11] add comment --- core/mise/mise.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/core/mise/mise.go b/core/mise/mise.go index b14b44d..2754d65 100644 --- a/core/mise/mise.go +++ b/core/mise/mise.go @@ -57,6 +57,7 @@ func (m *Mise) runCmd(args ...string) (string, error) { dataDir := filepath.Join(m.cacheDir, "data") fileLockPath := filepath.Join(m.cacheDir, "lock") + // We want to use a file lock to prevent races when using mise in parallel mu, err := filemutex.New(fileLockPath) if err != nil { return "", fmt.Errorf("failed to create mutex: %w", err) @@ -80,19 +81,8 @@ func (m *Mise) runCmd(args ...string) (string, error) { fmt.Sprintf("MISE_CACHE_DIR=%s", cacheDir), fmt.Sprintf("MISE_DATA_DIR=%s", dataDir), fmt.Sprintf("PATH=%s", os.Getenv("PATH")), - - // We want to shell out to the git CLI here - // Without it, I was noticing races when multiple processes tried to check the version of the same package in parallel - // Sometimes a checkout operation would fail. - // I am testing out forcing usage of the git CLI to see if it helps - // Source: https://github.com/jdx/mise/blob/main/src/git.rs#L124 - // Config: https://github.com/jdx/mise/blob/main/settings.toml#L369 - // "MISE_GIX=false", - // "MISE_LIBGIT2=false", ) - // cmd.Env = append(cmd.Env, os.Environ()...) - if err := cmd.Run(); err != nil { return "", fmt.Errorf("failed to run mise command '%s': %w\nstdout: %s\nstderr: %s", strings.Join(append([]string{m.binaryPath}, args...), " "),