vuer-release build/release flow (release-tool CLI internals)
The release tool is readable source, not a black box
TechTeamer/vuer-release-cliis a plain Python repo. Therelease_toolbinary published as a GitHub release asset is just a packaged build of it. Everything below was read out of that source on 2026-07-22 and corrects several assumptions previously inferred from artifacts (release.jsonfiles, Dockerfiles, Harbor tags).Companion notes: vuer-release-cut-recipe = how to cut a release; this note = what the tool actually does when you do.
The flow end to end
release-tool release create project <p> (local, interactive)
│ asks VERSION / BUILD_NUMBER / TAG per component
▼
projects/<p>/release/<N>/release.json → commit → push tag <p>@<N> (or base@<N>)
▼ tag matching *@*
.github/workflows/autobuild.yml (self-hosted runner)
│ parse NAME@VERSION → checkout
│ secrets.RELEASE_PAT → ~/.git-credentials (HTTPS, x-access-token)
│ download release_tool asset from TechTeamer/vuer-release-cli
▼
release-tool gen project|base → build project|base → publish login/push
HARBOR_USER / HARBOR_SECRET
- Developer, locally:
release-tool release create project <project>prompts forVERSION/BUILD_NUMBER/TAGper component, writesprojects/<p>/release/<N>/release.json, commits it, pushes the git tag<p>@<N>. - Tag push matching
*@*fires.github/workflows/autobuild.ymlon a self-hosted runner. - Workflow: parse
NAME@VERSIONfrom the tag → checkout → writesecrets.RELEASE_PATinto~/.git-credentials(HTTPS auth asx-access-token) → download therelease_toolasset →gen→build→publish login+publish pushto Harbor withHARBOR_USER/HARBOR_SECRET.
release create vs gen — who writes what
release createwritesCOMPONENT_LIST.genonly reads it.A common mis-model is that
gensnapshots the component config intorelease.jsonat build time. It does not — the two steps are cleanly separated.
Step 1 — release create (interactive, local):
commands/release/release.py:239-259get_project_component_env_values()merges base then project: readsbase/components/<c>/component_env_values.json, thenprojects/<p>/components/<c>/component_env_values.json, doesenv_values.pop("PROJECT_NAME", "")andenv_values.update(project_env_values)→ project wins.release.py:284-297ask_component_env_values()→release.py:269-281ask_env_values()prompts for every key, with the merged value asdefault=value.- The confirmed values are written to
projects/<p>/release/<N>/release.json(release.py:356).
So component_env_values.json supplies interactive prompt defaults, not an automatic snapshot. The operator confirms or overrides.
Step 2 — gen (CI): commands/gen/gen.py:76 is return release_json["COMPONENT_LIST"]. It reads release.json only and never re-reads component_env_values.json. Once release.json exists, the component env files are irrelevant to the build.
TAGis NOT a required env value — omit it and the component is silently never cloned
REQUIRED_ENV_VALUES = {"VERSION": "", "BUILD_NUMBER": ""}(release.py:49), merged viawith_required_env_values()(release.py:262-266).TAGis not in that set — it is prompted only if it already appears in the merged component env values.
- By design for janus:
janushas noTAGkey inbase/components/janus/component_env_values.jsonnor in any partner’s janus file → janus never gets a TAG →has_source()is false → the CLI never clones janus. Its source is fetched byinstall/install-janus-build-env.shfromJANUS_REPOSITORY+JANUS_VERSION_COMMIT.- The trap: add a new base component and forget
TAGin itscomponent_env_values.json, and it will silently never be cloned — no error, just missing source.
Where the janus pin really lives
projects/<p>/components/janus/component_env_values.json(VERSION/JANUS_REPOSITORY/JANUS_VERSION_COMMIT/BUILD_NUMBER) is the default at therelease createprompt; pressing enter accepts it intorelease.json. Effective, but overridable at release time — not immutable. This corrects the older claim in vuer-release-cut-recipe thatgenoverwrites hand-set pins.
Corrections (each verified in CLI source)
TAG— notVERSION— is the git ref the source is fetched from
gen.py::download_sourcecallsgit.pull_remote_tag(owner_url, repo_name=component["NAME"], tag=component["TAG"], …)→git clone --branch <TAG> --single-branch --depth 1.
VERSIONis used only for the image-tag string and the generated.env:make_image_tag→{registry}/{PROJECT_NAME}/{NAME}:{VERSION}.{BUILD_NUMBER}-{SECURITY_NUMBER}.Evidence:
projects/nusz/release/16/release.jsonpins vuer_ossVERSION 1.9.11.47/TAG nusz-1.9.11.47, and thevuer_ossrepo has no bare1.9.11.47tag. Partner tags look likenusz-1.9.11.47,demo-1.9.11.29,dap-1.9.11.NN.
A new base component does NOT need its own
base@Nrelease first
BASE_COMPONENT_IMAGE_TAG/PROJECT_COMPONENT_IMAGE_TAG/RELEASE_COMPONENT_IMAGE_TAGare all the same locally-computed string and are never resolved against the registry.
build.py::build_project_componentsbuilds the base stage first (contextbase/components/<NAME>), then the project stage, whoseFROM $BASE_COMPONENT_IMAGE_TAGresolves to the just-built local image.Corroborating artifacts:
vuer_css/vuer_ossappear in zerobase/release/*/release.json, yet every partner doesFROM $BASE_COMPONENT_IMAGE_TAG; anddemo-project@1built resource-manager1.0.3whilebase@5had published1.0.7.Only hard requirement:
base/components/<NAME>/Dockerfileexists.
Component NAME == GitHub repo name (no override key exists)
repo_name = component["NAME"], cloned fromGIT_REMOTE_ORG=https://github.com/TechTeamer. There is no repo-override key in the CLI, so a component directory name must equal its GitHub repo name.
JANUS_REPOSITORYis a red herring — it is consumed only byinstall/install-janus-build-env.shfor the janus sourcewget, never by the CLI clone.
gen.py::rm_alwayssanitizes the source tree before packaging: removes.yarnrc,config/dev.json,.git, and everysupervisor_*/nginx_*file whose name does not containdocker. That is why app repos can safely ship*_dev.confvariants next to*_docker.confeven thoughinstall/configure-app.shsymlinks allsupervisor*.conf/nginx*.confinto the conf dirs.- Tarball layout:
make_source_package→<NAME>-<TAG>;pkg/util.py::tarball_dirtars with the directory named<NAME>, so the archive’s top-level dir is the component NAME. Hence base Dockerfiles can docd /workspace && tar -xzf … && chown -R $DOCKER_USER:$DOCKER_USER $NAMEwithENV APP_HOME /workspace/$NAME. - A component is “available” to a project purely by having a directory at
projects/<p>/components/<c>/.pkg/ensure.py::project_componentslistscomponents.subdirs()and hard-failsUnknown componentotherwise. Inside that dir bothcomponent_env_values.jsonandDockerfileare optional (get_json(default={}); gen/build guard with.exists()). Therelease/.gitkeepfile is required, becauseReleaseDir.next_release_version()callssubdirs().
Do NOT scaffold with
release-tool component create
release_tool/template/component.j2is stale: it emits the old--mount=…,source=/installstyle instead offrom=install-scripts, plus a mangled nginx/redis block. Copy an existingbase/components/*/Dockerfileinstead.
Pre-existing latent issue
base/release/6listspdfservice, butTechTeamer/pdfservicedoes not resolve → a re-run ofgen base -r 6would break.
Applied to FKITDEV-8349 (DÁP)
Branch feat/FKITDEV-8349-dap in vuer-release, commits 97149bd + 409a28e, solo-author Andras Lederer <25370292+wowjeeez@users.noreply.github.com>, subject-only commit messages.
Adds projects/dap/ (janus 1.4.1 / cc0fdca8, vuer_css, vuer_oss, resource-manager, dap-demo-partner) plus a new base component base/components/dap-demo-partner/, derived from base/components/vuer_css/Dockerfile minus install-redis.sh (the app needs nginx, has no redis client).
- The legacy
vuer_build/partner/dap/dap_demo_partner/image is obsolete. It was a bespoke 2-stage UBI8 build that cloneddap-demo-partner.gitin-build using an SSH deploy key (docker_dap_demo_partner.key, never committed —.gitignorehas*.key). The CLI clones over HTTPS withRELEASE_PAT: no SSH key, no new repo secret. - Naming is forced: the component must be
dap-demo-partner(hyphens), because NAME → repo name anddap_demo_partnerwould 404. This renames the published imageharbor.techteamer.com/dap-facekom/dap_demo_partner:…→…/dap-demo-partner:…— a deployment-visible change. - Release-time
TAGvalues (the easy mistake):component TAG shape note dap-demo-partner1.0.7.1repo tags are 1.0.0.1 … 1.0.7.1— there is no bare1.0.7resource-manager1.0.8plain tags vuer_css/vuer_ossdap-1.9.11.NNpartner-prefixed - Merge to
masterbeforerelease create— the CLI tags from the current branch.
Related
vuer-release-cut-recipe · FKITDEV-8349 · FKITDEV-8344-vuer-release-migration-batch · FKITDEV-8354-mvm-supervisor-config-dedup · FKITDEV-8252 · release-process · release-automation-design · client-registry · FaceKom