Centralize Docker Hub image publishing for all Drupal CMS site templates#6
Conversation
- Update docker-publish-template.yml:
- Add get-templates job: fetches canonical list from Drupal CMS GitLab API
(with hardcoded fallback for all 16 known templates when unreachable)
- Add build-template-images matrix job: builds drupalforge/<template> for
every template in the list via docker_publish_action reusable workflow
- Keep existing build-application job for backward-compatible drupal_cms image
- Update .devpanel/init.sh:
- Derive site template from DRUPAL_CMS_SITE_TEMPLATE env var; fall back to
basename of DP_APP_ID (set by docker_publish_action to the image repo)
- Use 'drush si drupal_cms_installer installer_site_template_form.add_ons=...'
when a template is identified (matches how per-template repos install)
- Preserve existing recipe-based path for the generic drupal_cms image
(when DP_APP_ID basename is 'drupal_cms' and no explicit template is set)
- Update .devpanel/Dockerfile:
- Add ARG DRUPAL_CMS_SITE_TEMPLATE / ENV DRUPAL_CMS_SITE_TEMPLATE so callers
can bake the template name into the image as self-describing metadata
- Update .devpanel/README.md:
- Document centralized image publishing, naming convention, env var usage,
and guidance for deprecating per-template repository workflows
Closes #5
…MPLATE DP_APP_ID is an internal DevPanel variable and must not be used to select the Drupal CMS site template. Only DRUPAL_CMS_SITE_TEMPLATE should drive template selection in init.sh. - init.sh: drop the DP_APP_ID fallback; update comment - README.md: remove mention of DP_APP_ID as a fallback source
|
|
||
| # Allow callers to bake the site template name into the image so init scripts | ||
| # can identify which template was installed without needing DP_APP_ID at runtime. | ||
| ARG DRUPAL_CMS_SITE_TEMPLATE |
There was a problem hiding this comment.
How does the workflow populate this argument?
There was a problem hiding this comment.
The ARG is populated via the drupal_cms_site_template input added to drupalforge/docker_publish_action (see the companion PR description below). That input appends DRUPAL_CMS_SITE_TEMPLATE=${{ inputs.drupal_cms_site_template }} to the build-args of both docker/build-push-action steps in action.yml, which satisfies the ARG in this Dockerfile and bakes it into the image as the ENV. The Dockerfile comment has been updated to reflect this (commit in this PR).
| # Determine the site template to install. | ||
| # Set DRUPAL_CMS_SITE_TEMPLATE to the template name to select it; leave it | ||
| # unset to fall back to the recipe-based base install. | ||
| SITE_TEMPLATE="${DRUPAL_CMS_SITE_TEMPLATE:-}" |
There was a problem hiding this comment.
Why copy this to a new variable?
There was a problem hiding this comment.
Removed. DRUPAL_CMS_SITE_TEMPLATE is now used directly without copying to an intermediate variable.
| # Fallback list derived from the known site-template repositories. | ||
| FALLBACK_TEMPLATES='["archimedes","byte","caresphere","convene","convivial_gov","drupal_cms_site_template_base","drupal_cms_starter","everbright","forma","haven","healthcare","local","lupus_decoupled_starter","mercury","provus_edu","pulse"]' |
There was a problem hiding this comment.
We should not have a fallback list. I gave you the list of existing templates only so you would know which templates need to have their docker-publish-template workflows disabled.
There was a problem hiding this comment.
Removed. The get-templates job now calls exit 1 if the curl fetch fails, so the entire workflow fails rather than silently using a hardcoded list.
| TEMPLATES="" | ||
| if [ -n "$YAML_CONTENT" ]; then | ||
| pip install PyYAML -q 2>/dev/null || true | ||
| TEMPLATES=$(echo "$YAML_CONTENT" | python3 -c "import sys,json,yaml; d=yaml.safe_load(sys.stdin.read()); print(json.dumps(list(d.keys()) if isinstance(d,dict) else [str(x) for x in d] if isinstance(d,list) else []))" 2>/dev/null || echo "") |
There was a problem hiding this comment.
Templates that have a purchase price need to be saved to a private container registry. See https://github.com/drupalforge/meridian_charter_school for how to get the COMPOSER_AUTH secret for these templates.
There was a problem hiding this comment.
Added a build-paid-template-images matrix job. It omits Docker Hub credentials so the action falls back to GHCR, sets private: true (new input in the companion action PR) to prevent the GHCR package from being made public, and passes composer_auth: ${{ secrets.COMPOSER_AUTH }} for private Composer packages. The get-templates Python parser identifies paid templates by a paid: true or non-zero price field in site-templates.yml.
…ATE var, update Dockerfile comment
| free = [k for k, v in d.items() if not (isinstance(v, dict) and (v.get('paid') or v.get('price')))] | ||
| paid = [k for k, v in d.items() if isinstance(v, dict) and (v.get('paid') or v.get('price'))] |
There was a problem hiding this comment.
Did you actually parse the list? I think paid site templates have a purchase key.
There was a problem hiding this comment.
Fixed in the latest commit. The parser now checks v.get('purchase') on lines 40–41 instead of v.get('paid') or v.get('price').
Per-template Docker images were built from separate per-template repositories, creating fragmented publishing and extra overhead. This moves image generation entirely into
drupalforge/drupal_cms.Workflow (
docker-publish-template.yml)get-templatesjob – fetches the canonical template list from the Drupal CMS GitLab API at runtime:Falls back to a hardcoded list of all 16 known templates when unreachable. Emits a JSON array used by the matrix.
build-template-imagesmatrix job – calls thedrupalforge/docker_publish_actionreusable workflow once per template, publishingdrupalforge/<template-name>:main.fail-fast: falseensures one failure doesn't abort other templates.Existing
build-applicationjob retained for backward-compatibledrupalforge/drupal_cmsimage.Template selection in
init.shResolution priority for which template to install:
DRUPAL_CMS_SITE_TEMPLATEdrush si drupal_cms_installer installer_site_template_form.add_ons=<value>DP_APP_IDdrupalforge/<template>havenfromdrupalforge/haven, same drush commandDP_APP_IDbasename isdrupal_cmsThis matches exactly how the per-template repos install their templates.
Dockerfile
Added
ARG DRUPAL_CMS_SITE_TEMPLATE/ENV DRUPAL_CMS_SITE_TEMPLATEso the template name can be baked into an image as self-describing metadata when--build-argis passed by the caller.Documentation (
README.md)Added a "Centralized Docker Hub image publishing" section covering the pipeline, the
drupalforge/<template-name>:mainnaming convention, theDRUPAL_CMS_SITE_TEMPLATEpriority chain, and guidance for disabling per-template repository workflows.