diff --git a/.github/workflows/drupal-contrib-integration-test.yml b/.github/workflows/drupal-contrib-integration-test.yml index af378e7..a7065be 100644 --- a/.github/workflows/drupal-contrib-integration-test.yml +++ b/.github/workflows/drupal-contrib-integration-test.yml @@ -92,9 +92,6 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} - - name: Copy VERSION into template directory - run: cp VERSION drupal-contrib/VERSION - - name: Push template (inactive) run: | coder templates push drupal-contrib \ @@ -102,6 +99,7 @@ jobs: --activate=false \ --name ${{ env.WORKSPACE_NAME }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev - name: Create workspace @@ -274,9 +272,6 @@ jobs: echo "ISSUE_BRANCH=$ISSUE_BRANCH" >> "$GITHUB_ENV" echo "ISSUE_FORK_VERSION=$DRUPAL_VERSION" >> "$GITHUB_ENV" - - name: Copy VERSION into template directory - run: cp VERSION drupal-contrib/VERSION - - name: Push template (inactive) run: | coder templates push drupal-contrib \ @@ -284,6 +279,7 @@ jobs: --activate=false \ --name cc-${{ github.run_number }}-${{ github.run_attempt }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev - name: Create workspace @@ -424,9 +420,6 @@ jobs: access_url: ${{ vars.TEST_CODER_URL }} coder_session_token: ${{ env.TEST_CODER_SESSION_TOKEN }} - - name: Copy VERSION into template directory - run: cp VERSION drupal-contrib/VERSION - - name: Push template (inactive) run: | coder templates push drupal-contrib \ @@ -434,6 +427,7 @@ jobs: --activate=false \ --name ${{ env.WORKSPACE_NAME }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ --variable github_token=${{ secrets.GITHUB_TOKEN }} @@ -579,9 +573,6 @@ jobs: echo "ISSUE_BRANCH=$ISSUE_BRANCH" >> "$GITHUB_ENV" echo "ISSUE_FORK_VERSION=$DRUPAL_VERSION" >> "$GITHUB_ENV" - - name: Copy VERSION into template directory - run: cp VERSION drupal-contrib/VERSION - - name: Push template (inactive) run: | coder templates push drupal-contrib \ @@ -589,6 +580,7 @@ jobs: --activate=false \ --name gc-${{ github.run_number }}-${{ github.run_attempt }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ --variable github_token=${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/drupal-integration-test.yml b/.github/workflows/drupal-integration-test.yml index 19b76e8..3b12d48 100644 --- a/.github/workflows/drupal-integration-test.yml +++ b/.github/workflows/drupal-integration-test.yml @@ -91,9 +91,6 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} - - name: Copy VERSION into template directory - run: cp VERSION drupal-core/VERSION - - name: Push template (inactive) run: | coder templates push drupal-core \ @@ -101,6 +98,7 @@ jobs: --activate=false \ --name ${{ env.WORKSPACE_NAME }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ --variable cache_path=/home/rfay/cache/drupal-core-seed \ --variable github_token=${{ secrets.GITHUB_TOKEN }} @@ -231,9 +229,6 @@ jobs: access_url: ${{ vars.TEST_CODER_URL }} coder_session_token: ${{ env.TEST_CODER_SESSION_TOKEN }} - - name: Copy VERSION into template directory - run: cp VERSION drupal-core/VERSION - - name: Push template (inactive) run: | coder templates push drupal-core \ @@ -241,6 +236,7 @@ jobs: --activate=false \ --name ${{ env.WORKSPACE_NAME }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ --variable cache_path=/home/rfay/cache/drupal-core-seed \ --variable github_token=${{ secrets.GITHUB_TOKEN }} @@ -337,9 +333,6 @@ jobs: echo "ISSUE_BRANCH=$ISSUE_BRANCH" >> "$GITHUB_ENV" echo "ISSUE_FORK_VERSION=$DRUPAL_VERSION" >> "$GITHUB_ENV" - - name: Copy VERSION into template directory - run: cp VERSION drupal-core/VERSION - - name: Push template (inactive) run: | coder templates push drupal-core \ @@ -347,6 +340,7 @@ jobs: --activate=false \ --name cd-${{ github.run_number }}-${{ github.run_attempt }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ --variable cache_path=/home/rfay/cache/drupal-core-seed \ --variable github_token=${{ secrets.GITHUB_TOKEN }} @@ -486,9 +480,6 @@ jobs: echo "ISSUE_BRANCH=$ISSUE_BRANCH" >> "$GITHUB_ENV" echo "ISSUE_FORK_VERSION=$DRUPAL_VERSION" >> "$GITHUB_ENV" - - name: Copy VERSION into template directory - run: cp VERSION drupal-core/VERSION - - name: Push template (inactive) run: | coder templates push drupal-core \ @@ -496,6 +487,7 @@ jobs: --activate=false \ --name gd-${{ github.run_number }}-${{ github.run_attempt }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ --variable cache_path=/home/rfay/cache/drupal-core-seed \ --variable github_token=${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 0250a64..b6a8504 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -114,9 +114,6 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} - - name: Copy VERSION into template directory - run: cp VERSION ${{ matrix.template }}/VERSION - - name: Push template (inactive) run: | coder templates push ${{ matrix.template }} \ @@ -124,6 +121,7 @@ jobs: --activate=false \ --name ci-${{ env.CI_TAG }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ ${{ matrix.extra_vars }} @@ -329,9 +327,6 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} - - name: Copy VERSION into template directory - run: cp VERSION ${{ matrix.template }}/VERSION - - name: Push template (inactive) run: | coder templates push ${{ matrix.template }} \ @@ -339,6 +334,7 @@ jobs: --activate=false \ --name ci-gh-${{ env.CI_TAG }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ ${{ matrix.extra_vars }} diff --git a/.github/workflows/staging-push.yml b/.github/workflows/staging-push.yml index 0f31fdf..4100cfa 100644 --- a/.github/workflows/staging-push.yml +++ b/.github/workflows/staging-push.yml @@ -67,9 +67,6 @@ jobs: access_url: ${{ vars.TEST_CODER_URL }} coder_session_token: ${{ env.TEST_CODER_SESSION_TOKEN }} - - name: Copy VERSION into template directory - run: cp VERSION ${{ matrix.template }}/VERSION - - name: Push template (inactive) run: | coder templates push ${{ matrix.template }} \ @@ -77,6 +74,7 @@ jobs: --activate=false \ --name ${{ env.VERSION_NAME }} \ --yes \ + --variable image_version="$(cat VERSION)" \ --variable workspace_image_registry=index.docker.io/ddev/coder-ddev \ ${{ matrix.extra_vars }} diff --git a/CLAUDE.md b/CLAUDE.md index ac3d778..d161fd0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -238,7 +238,7 @@ The startup script is inline in each template's `template.tf` (e.g. `freeform/te ### Terraform Variables Key template variables (e.g. in `freeform/template.tf`): - `workspace_image_registry` - Docker registry URL (default: `index.docker.io/ddev/coder-ddev`) -- `image_version` - Image tag (default: read from `VERSION` file or `v0.1`) +- `image_version` - Image tag (default: `v0.1`; the Makefile passes `--variable image_version=$(cat VERSION)` at push time, so the root `VERSION` file is the single source of truth — no per-template copies) - `cpu` / `memory` - Resource limits (defaults: 4 cores, 8GB RAM) - `node_version` - Node.js version (default: `24`, informational only — Node is pre-installed in image) - `docker_gid` - Docker group GID (default: `988`) @@ -352,6 +352,6 @@ Additional logs in workspace: - `scripts/coder-delete-workspace-dir.sh` - Sudo wrapper for workspace host dir cleanup (must be installed on server) - `scripts/cleanup-deleted-workspaces.sh` - Manual cleanup for orphaned workspace dirs/volumes - `scripts/workspace-lifecycle-cleanup.sh` - Notifies then deletes idle workspaces; runs via systemd timer on coder.ddev.com (production only, see `scripts/workspace-lifecycle-cleanup.service`/`.timer`, must be installed on server) -- `VERSION` - Image version used by all templates (read automatically by Makefile) +- `VERSION` - Single source of truth for the image version; read by the Makefile and passed to every template as `--variable image_version=...` at push time (no per-template copies) - `openspec/project.md` - Project conventions and constraints - `openspec/AGENTS.md` - OpenSpec workflow instructions diff --git a/Makefile b/Makefile index 7830687..d544682 100644 --- a/Makefile +++ b/Makefile @@ -44,10 +44,8 @@ TEMPLATE_EDIT_freeform := --display-name "DDEV Freeform" \ # Shared recipe for pushing any template (call with template name as argument) define push_template - @echo "Syncing VERSION to $(1)..." - cp VERSION $(1)/VERSION - @echo "Pushing Coder template $(1)..." - coder templates push --directory $(1) $(1) --yes --activate=$(ACTIVATE) $(TEMPLATE_VARS_$(1)) + @echo "Pushing Coder template $(1) (image_version=$(VERSION))..." + coder templates push --directory $(1) $(1) --yes --activate=$(ACTIVATE) --variable image_version=$(VERSION) $(TEMPLATE_VARS_$(1)) @echo "Setting template metadata for $(1)..." coder templates edit $(1) --yes $(TEMPLATE_EDIT_$(1)) @echo "Template $(1) push complete" diff --git a/drupal-contrib/.gitignore b/drupal-contrib/.gitignore new file mode 100644 index 0000000..f1601ee --- /dev/null +++ b/drupal-contrib/.gitignore @@ -0,0 +1,5 @@ +# Vault token file (not committed to Git) +vault-token.txt + +# Terraform working directory +.terraform/ diff --git a/drupal-contrib/VERSION b/drupal-contrib/VERSION deleted file mode 100644 index 1811f96..0000000 --- a/drupal-contrib/VERSION +++ /dev/null @@ -1 +0,0 @@ -v0.4 diff --git a/drupal-contrib/template.tf b/drupal-contrib/template.tf index 847dec5..7053689 100644 --- a/drupal-contrib/template.tf +++ b/drupal-contrib/template.tf @@ -219,7 +219,7 @@ locals { } locals { - image_version = try(trimspace(file("${path.module}/VERSION")), var.image_version) + image_version = var.image_version registry_without_version = replace(var.workspace_image_registry, ":${local.image_version}", "") workspace_image_registry_base = replace(local.registry_without_version, ":latest", "") } diff --git a/drupal-core/.gitignore b/drupal-core/.gitignore index b1671c7..f1601ee 100644 --- a/drupal-core/.gitignore +++ b/drupal-core/.gitignore @@ -1,8 +1,5 @@ # Vault token file (not committed to Git) vault-token.txt -# VERSION is copied from root by Makefile before push -VERSION - # Terraform working directory .terraform/ diff --git a/drupal-core/template.tf b/drupal-core/template.tf index 898991b..2c19b02 100644 --- a/drupal-core/template.tf +++ b/drupal-core/template.tf @@ -212,8 +212,8 @@ locals { } locals { - # Read image version from VERSION file if it exists, otherwise use variable default - image_version = try(trimspace(file("${path.module}/VERSION")), var.image_version) + # Set via --variable image_version=$(cat VERSION) by the Makefile at push time. + image_version = var.image_version # Remove any tag (including :latest) if present, but preserve port numbers (e.g., :5050) # Remove common tags from the end of the registry URL @@ -252,7 +252,7 @@ variable "vscode_extensions" { variable "workspace_image_registry" { description = "Docker registry URL for the workspace base image (without tag, version is added automatically)" type = string - # The version tag is appended automatically using the image_version variable or VERSION file + # The version tag is appended automatically using the image_version variable. # DO NOT include :latest or any version tag here - version comes from image_version variable # To use a specific version, override the image_version variable when deploying default = "index.docker.io/ddev/coder-ddev" @@ -262,7 +262,7 @@ variable "workspace_image_registry" { # The image is built and pushed using the Makefile (see root Makefile and VERSION file) # This avoids prevent_destroy issues since the image is not managed by Terraform resource "docker_image" "workspace_image" { - # Always use version tag (never :latest) from the image_version variable or VERSION file + # Always use version tag (never :latest) from the image_version variable. # This ensures consistent image versions and prevents using stale images name = "${local.workspace_image_registry_base}:${local.image_version}" diff --git a/freeform/.gitignore b/freeform/.gitignore index b1671c7..f1601ee 100644 --- a/freeform/.gitignore +++ b/freeform/.gitignore @@ -1,8 +1,5 @@ # Vault token file (not committed to Git) vault-token.txt -# VERSION is copied from root by Makefile before push -VERSION - # Terraform working directory .terraform/ diff --git a/freeform/template.tf b/freeform/template.tf index 997b0c4..9283a45 100644 --- a/freeform/template.tf +++ b/freeform/template.tf @@ -98,7 +98,7 @@ data "coder_parameter" "vscode_extensions" { locals { workspace_home = "/home/coder" selected_extensions = jsondecode(data.coder_parameter.vscode_extensions.value) - image_version = try(trimspace(file("${path.module}/VERSION")), var.image_version) + image_version = var.image_version registry_without_version = replace(var.workspace_image_registry, ":${local.image_version}", "") workspace_image_registry_base = replace(local.registry_without_version, ":latest", "")