This document explains how shared code is maintained across features in this repository.
Multiple features need the same helper functions (e.g., user selection logic). The devcontainer specification currently packages each feature independently and doesn't support sharing code between features at runtime.
We maintain a single source of truth with a CI-time sync mechanism to deploy to each feature:
- Location:
scripts/lib/common-setup.sh - Contains: Shared helper functions (currently user selection logic)
- Maintenance: All updates happen here
- Mechanism:
scripts/sync-common-setup.sh(runs automatically in CI) - Target: Copies to each feature's directory as
common-setup.shat build/test time - Reason: Devcontainer packaging requires files to be within each feature's directory
- Note: The copies are
.gitignored — only the source file is tracked in git
- Edit the source: Modify
scripts/lib/common-setup.sh - Test: Run
bash test/_global/test-common-setup.sh - Commit: Only the source file needs to be committed
# Edit the source
vim scripts/lib/common-setup.sh
# Test
bash test/_global/test-common-setup.sh
# Commit just the source
git add scripts/lib/common-setup.sh
git commit -m "Update common-setup.sh helper function"To generate the copies locally (e.g., for testing features outside CI):
./scripts/sync-common-setup.shAll CI workflows (test, release, stress test) automatically run sync-common-setup.sh
after checkout and before the devcontainer CLI packages features. This ensures the
copies are always present and up-to-date without tracking them in git.
The devcontainer CLI packages each feature independently. When a feature is installed:
- Only files within the feature's directory are included in the package
- Parent directories (
../common) are not accessible - Hidden directories (
.common) are excluded from packaging - Sibling feature directories are not accessible
This is a design decision in the devcontainer specification to ensure features are portable and self-contained.
The devcontainer spec has a proposal for an include property in devcontainer-feature.json (spec#129) that would enable native code sharing. Once implemented, the sync mechanism can be removed in favor of declarative includes:
{
"id": "my-feature",
"include": ["../../scripts/lib/common-setup.sh"]
}As of this PR:
- Source:
scripts/lib/common-setup.sh(87 lines) - Deployed: 16 features, each with
src/FEATURE/common-setup.sh(generated at CI time, gitignored) - Sync Script:
scripts/sync-common-setup.sh(called by all CI workflows) - Tests:
test/_global/test-common-setup.sh(14 test cases) - Benefits: Eliminated ~188 lines of inline duplicated logic from install scripts, zero duplicate files tracked in git
- Devcontainer Spec Issue #129 - Share code between features
- Features Library Proposal
- Test documentation:
test/_global/test-common-setup.sh - Sync script documentation:
scripts/README.md