Investigate: dev-template.sh v1.5.0 missing placeholder substitution
IMPLEMENTATION RULES: Before implementing this plan, read and follow:
- WORKFLOW.md - The implementation process
- PLANS.md - Plan structure and best practices
Status: Completed​
Goal: Determine the best approach to restore placeholder substitution in dev-template.sh and remove the obsolete urbalurba-scripts/ copy block.
GitHub Issue: #67
Last Updated: 2026-03-04
Questions to Answer​
- Where exactly in the current
dev-template.sh(v1.5.0) shouldreplace_placeholders()be restored? - Which files need substitution after the
ingress.yamlremoval? - Are there any other placeholders beyond
{{REPO_NAME}}and{{GITHUB_USERNAME}}? - Where is the
urbalurba-scripts/copy block and what exactly does it copy? - Are there any downstream effects of removing the
urbalurba-scripts/copy?
Current State​
When dev-template.sh was moved from urbalurba-dev-templates to devcontainer-toolbox, the replace_placeholders() function was not carried over. The current v1.5.0 copies template files as-is without substituting {{REPO_NAME}} and {{GITHUB_USERNAME}}.
Impact — entire deploy chain is broken​
Without substitution, three things fail in sequence:
manifests/deployment.yamlcontains literal{{REPO_NAME}}-deployment— not a valid Kubernetes resource name- GitHub Actions workflow sed pattern doesn't match the un-substituted placeholders — silently does nothing
- ArgoCD cannot sync because the manifests contain invalid YAML values
What the old version had​
The v1.1.0 script had a replace_placeholders() function (lines 540-562) that ran sed substitution on {{GITHUB_USERNAME}} and {{REPO_NAME}} across manifests/*.yaml and .github/workflows/*.yaml.
Fix 1: Restore placeholder substitution​
Restore the replace_placeholders() function from v1.1.0 into dev-template.sh. Call it on manifests/*.yaml after copy_template_files() completes.
Files that need substitution:
manifests/deployment.yaml— 8 ×{{REPO_NAME}}, 2 ×{{GITHUB_USERNAME}}manifests/kustomization.yaml— 2 ×{{REPO_NAME}}, 2 ×{{GITHUB_USERNAME}}.github/workflows/urbalurba-build-and-push.yaml— no fix needed (uses GitHub context variables)
Fix 2: Remove urbalurba-scripts/ copy block​
The copy_template_files() function copies the urbalurba-scripts/ directory into new projects. This directory contains obsolete registration scripts (register-argocd.sh, remove-argocd.sh, check-deployment.sh, etc.) that predate the uis CLI.
All functionality is now handled by uis argocd register/remove/list/verify. The copy block should be removed.
Investigation Tasks​
- Read current
dev-template.shto understand the structure and findcopy_template_files() - Locate the
urbalurba-scripts/copy block - Check the old v1.1.0
replace_placeholders()function inurbalurba-dev-templates - Verify which placeholders exist in the template files
- Determine if any other scripts depend on
urbalurba-scripts/being present - Assess whether this is a simple restore or needs redesign
Investigation Findings​
Q1: Where should replace_placeholders() be restored?​
The current script flow in dev-template.sh (v1.5.0) is:
check_prerequisites → download_templates → scan_templates → select_template
→ verify_template → copy_template_files → setup_github_workflows → merge_gitignore
→ cd $OLDPWD → cleanup_and_complete
The substitution must happen after copy_template_files() and setup_github_workflows() copy files into $OLDPWD, but before cleanup_and_complete(). A new replace_placeholders() function + a process_essential_files() caller should be added between merge_gitignore and cd "$OLDPWD" (around line 467).
Critical missing piece: The current v1.5.0 script has no code to extract GITHUB_USERNAME and REPO_NAME from the git remote.
Existing library: .devcontainer/additions/lib/git-identity.sh already provides:
parse_git_remote_url()— parses GitHub (HTTPS+SSH), Azure DevOps, and generic remotesdetect_git_identity()— full detection with fallbacks, exportsGIT_ORGandGIT_REPO
The script should source lib/git-identity.sh and call detect_git_identity — no need to write custom detection.
Validation must happen early — before downloading templates. The script should:
- Source
git-identity.shand calldetect_git_identity - Validate that
GIT_ORGis not empty (needed forghcr.io/{{GITHUB_USERNAME}}/...) - Validate that
GIT_REPOis not empty - Abort with a clear error if either is missing, explaining what the user needs to do (e.g.,
git remote add origin ...) - Only then proceed to
download_templates
Updated flow:
check_prerequisites → detect_and_validate_repo_info → download_templates → scan_templates
→ select_template → verify_template → copy_template_files → setup_github_workflows
→ merge_gitignore → replace_placeholders → cd $OLDPWD → cleanup_and_complete
Edge cases where GIT_ORG would be empty:
- No git repo initialized (
git initnot run) - No remote configured (
git remote add originnot run) - Non-GitHub/Azure DevOps remote (generic fallback sets
GIT_ORG="")
All of these should produce a clear error message before any template work begins.
Q2: Which files need substitution?​
Confirmed from ALL 7 template source directories:
manifests/deployment.yaml— all 7 templates:{{REPO_NAME}},{{GITHUB_USERNAME}}manifests/kustomization.yaml— all 7 templates:{{REPO_NAME}},{{GITHUB_USERNAME}}.github/workflows/urbalurba-build-and-push.yaml— 4 of 7 templates (csharp, golang, java, php) contain{{REPO_NAME}}and{{GITHUB_USERNAME}}placeholders
Correction from initial analysis: The issue stated workflows don't need substitution. This is wrong for 4 templates. The substitution must run on both manifests/*.yaml AND .github/workflows/*.yaml.
No ingress.yaml files exist in any template (already removed).
Q3: Any other placeholders?​
No custom template placeholders beyond {{REPO_NAME}} and {{GITHUB_USERNAME}}. The ${{ ... }} patterns in workflow files (e.g., ${{ github.repository }}, ${{ secrets.GITHUB_TOKEN }}) are GitHub Actions context variables — these must NOT be touched by the sed substitution. The {{ vs ${{ distinction is important.
Q4: Where is the urbalurba-scripts/ copy block?​
Lines 363-369 of the current dev-template.sh:
if [ -d "$TEMPLATE_REPO_NAME/urbalurba-scripts" ]; then
echo " Setting up urbalurba-scripts..."
mkdir -p "$OLDPWD/urbalurba-scripts"
cp -r "$TEMPLATE_REPO_NAME/urbalurba-scripts/"* "$OLDPWD/urbalurba-scripts/"
chmod +x "$OLDPWD/urbalurba-scripts/"*.sh 2>/dev/null || true
echo " ✅ Added urbalurba-scripts"
fi
Q5: Any downstream effects of removing urbalurba-scripts/?​
None. The urbalurba-scripts/ directory no longer exists on the remote urbalurba-dev-templates repo (confirmed via GitHub API — returns 404). The copy block is already dead code. Removing it is safe.
Q6: Simple restore or redesign?​
Simple restore with several improvements. The fix requires:
- Add path resolution (
SCRIPT_DIR,ADDITIONS_DIR) — same pattern asdev-setup.shanddev-help.sh - Source existing
lib/git-identity.shand calldetect_git_identityearly (before downloading) - Validate
GIT_ORGandGIT_REPOare not empty — abort with clear error if missing - Replace
$OLDPWDusage with explicitCALLER_DIR="$PWD"captured at script start - Add
replace_placeholders()function using$GIT_ORGand$GIT_REPO(adapted from v1.1.0) - Add
process_essential_files()to call it onmanifests/*.yamlAND.github/workflows/*.yaml - Remove the
urbalurba-scripts/copy block (lines 363-369) - Bump
SCRIPT_VERSIONto 1.6.0
Reuses existing git-identity.sh library rather than duplicating detection logic.
Gaps Found During Validation​
Gap 1: Workflow files need substitution too​
The issue and initial analysis stated .github/workflows/*.yaml don't need substitution. This is wrong. 4 of 7 templates (csharp, golang, java, php) have {{REPO_NAME}} and {{GITHUB_USERNAME}} in their workflow files. Must substitute both manifests/*.yaml and .github/workflows/*.yaml.
Important: The sed pattern {{REPO_NAME}} must NOT match ${{ github.repository }} or other GitHub Actions context variables. The existing sed from v1.1.0 uses exact match (s|{{GITHUB_USERNAME}}|...|g) which is safe — ${{ won't match {{.
Gap 2: $OLDPWD is fragile​
The script uses $OLDPWD throughout (lines 361, 365-367, 380-381, 394-408) to write files back to the user's project. This relies on cd "$TEMP_DIR" being the only cd in the script. But detect_git_identity() also does cd /workspace internally, which would corrupt $OLDPWD.
Fix: Capture CALLER_DIR="$PWD" at script start and replace all $OLDPWD references with $CALLER_DIR.
Gap 3: No path resolution for sourcing libraries​
dev-template.sh has no SCRIPT_DIR/ADDITIONS_DIR path calculation. It cannot source git-identity.sh without this. Other manage/ scripts (dev-help.sh, dev-setup.sh) already have this pattern:
SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
DEVCONTAINER_DIR="$(dirname "$SCRIPT_DIR")"
ADDITIONS_DIR="$DEVCONTAINER_DIR/additions"
Gap 4: detect_git_identity() changes working directory​
The function does cd "$workspace_dir" (defaults to /workspace). If called after cd "$TEMP_DIR", it changes the cwd back. If called before, it sets cwd to /workspace, and then cd "$TEMP_DIR" overwrites it. Using CALLER_DIR instead of $OLDPWD eliminates this fragility regardless of call order.
Gap 5: Non-GitHub providers​
Templates use ghcr.io/{{GITHUB_USERNAME}}/{{REPO_NAME}} — this is GitHub Container Registry. If GIT_PROVIDER is azure-devops, GIT_ORG maps to an Azure DevOps org, not a GitHub username. The image path would be technically wrong. For now, the templates are GitHub-only, so the validation should check GIT_PROVIDER == "github" and warn (but not block) for other providers.
Recommendation​
Create a single PLAN file with four phases:
- Phase 1: Add path resolution and
CALLER_DIR— replace all$OLDPWDusage, addSCRIPT_DIR/ADDITIONS_DIRcalculation - Phase 2: Add repo info detection and validation — source
git-identity.sh, calldetect_git_identity, validateGIT_ORG/GIT_REPObefore downloading templates - Phase 3: Add
replace_placeholders()+process_essential_files()— substitute bothmanifests/*.yamland.github/workflows/*.yaml - Phase 4: Remove
urbalurba-scripts/copy block + bump version to 1.6.0
Next Steps​
- Create PLAN-dev-template-placeholder-fix.md with the approach above