@@ -4,17 +4,14 @@ Use this template when the repository has multiple frontend modules such as `web
## Replace these placeholders
-`__RUNNER_TAG__`
-`__BUILD_IMAGE__`
-`__RELEASE_IMAGE__`
-`__WEB_PACKAGE_DIR__`
-`__WEB_INSTALL_COMMAND__`
-`__WEB_PACKAGE_MANAGER__`
-`__WEB_BUILD_COMMAND__`
-`__WEB_DIST_SUBDIR__`
-`__WEB_OSS_NAME__`
-`__WEB_TAG_PREFIX__`
-`__ADMIN_PACKAGE_DIR__`
-`__ADMIN_INSTALL_COMMAND__`
-`__ADMIN_PACKAGE_MANAGER__`
-`__ADMIN_BUILD_COMMAND__`
-`__ADMIN_DIST_SUBDIR__`
-`__ADMIN_OSS_NAME__`
...
...
@@ -28,18 +25,42 @@ Use this template when the repository has multiple frontend modules such as `web
4. Dist directories are normalized to `/cache/transfer/${CI_PIPELINE_ID}/web/dist` and `/cache/transfer/${CI_PIPELINE_ID}/admin/dist`.
5. Only tags matching the configured module prefix trigger that module pair.
6. Prefer an official Node image such as `node:16-alpine` or `node:24-alpine`, selected from project evidence.
7. Each build script checks the real lockfile state first, so pnpm repositories without `pnpm-lock.yaml` automatically fall back to `pnpm install --no-frozen-lockfile`.
8. For Bingo / SGKT family repositories, `release_*` defaults to `springjk/ci-helper:latest` and all concrete jobs default to `tags: ["web"]`.
9. Each `release_*` keeps the contract `sh ci/release-dist.sh "$MODULE_NAME" "$OSS_DEPLOY_NAME"` and this skill does not downgrade release to artifacts-only.
## Package manager rule
Choose each module's install and build commands from the checked-in repository:
- npm module: `__WEB_INSTALL_COMMAND__` could be `npm install`, `__WEB_BUILD_COMMAND__` could be `npm run build`
- pnpm module: `__ADMIN_INSTALL_COMMAND__` could be `pnpm install --frozen-lockfile`, `__ADMIN_BUILD_COMMAND__` could be `pnpm run build --filter=@vben/web-antdv-next`
- yarn module: use `yarn install --frozen-lockfile` plus the module's real build command
- First verify whether these files really exist in the repository: `package.json`, `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `pnpm-workspace.yaml`
- Also verify each module's real build entrypoints from `package.json` scripts, existing `build*.sh`, and existing `ci/*.sh`
- npm module: set `__WEB_PACKAGE_MANAGER__` or `__ADMIN_PACKAGE_MANAGER__` to `npm`, then use the module's real `__WEB_BUILD_COMMAND__` or `__ADMIN_BUILD_COMMAND__`
- pnpm module with `pnpm-lock.yaml`: set the module package manager to `pnpm`, then use the real build command
- pnpm module without `pnpm-lock.yaml`: still use `pnpm`, but let the script fall back to `pnpm install --no-frozen-lockfile` and keep the warning in logs
- yarn module with `yarn.lock`: use `yarn` plus the module's real build command
- yarn module without `yarn.lock`: let the script fall back to `yarn install`
Do not assume all modules use `pnpm` just because one copied project note mentions it.
Do not hardcode `pnpm install --frozen-lockfile` unless the repository actually contains `pnpm-lock.yaml`.
If documentation or copied samples claim a lockfile exists but the repository does not contain it, follow the repository state and update the docs to match.
Do not use `npm ci` as the default npm install command in this template.
## Release contract rule
When the target repository is part of the Bingo / SGKT family and no stronger repository-specific contract overrides it, keep these elements together:
For `__WEB_OSS_NAME__`, `__ADMIN_OSS_NAME__`, and similar values, distinguish between:
- confirmed mappings from the current repository or explicit user input
- inferred mappings from same-family repository naming patterns
If a mapping is inferred, call it out in the final explanation and tell the user they only need to adjust the variable value if the real OSS name differs.
## Prefix design rule
On older GitLab versions, use simple non-overlapping prefixes.
@@ -11,15 +11,12 @@ Use this template when the project needs:
## Replace these placeholders
-`__PACKAGE_DIR__`
-`__RUNNER_TAG__`
-`__BUILD_IMAGE__`
-`__RELEASE_IMAGE__`
-`__BUILD_TARGET__`
-`__INSTALL_COMMAND__`
-`__PACKAGE_MANAGER__`
-`__BUILD_COMMAND__`
-`__MODULE_NAME__`
-`__JOB_SUFFIX__`
-`__TAG_PREFIX__`
-`__OSS_DEPLOY_NAME__`
## Required files
...
...
@@ -29,24 +26,55 @@ Use this template when the project needs:
## Default behavior
1. Build job installs dependencies and runs one target build command.
1. Build job first checks the real repository files, then installs dependencies and runs one target build command.
2. Dist is copied to `$TRANSFER_BASE_DIR/<target>/dist`.
3. Release job creates dated and latest zip files.
4. Each zip is staged inside an upload directory before calling `oss-deploy`.
5. Only tags matching `__TAG_PREFIX__*` trigger this job pair.
6. Prefer an official Node image such as `node:16-alpine` or `node:24-alpine`, selected from project evidence.
7. If the repo uses pnpm but has no `pnpm-lock.yaml`, the build script logs the mismatch and falls back to `pnpm install --no-frozen-lockfile`.
8. For Bingo / SGKT family repositories, `release` defaults to `springjk/ci-helper:latest` and all concrete jobs default to `tags: ["web"]`.
9. The release command shape stays `sh ci/release-dist.sh "$BUILD_TARGET" "$OSS_DEPLOY_NAME"` and this skill does not downgrade release to artifacts-only.
## Package manager rule
Choose install and build commands from the checked-in repository, not from copied comments:
Choose package manager and build command from the checked-in repository, not from copied comments.
Before finalizing CI, verify whether these files really exist in the repository:
- npm repo: `__INSTALL_COMMAND__` might be `npm install`, `__BUILD_COMMAND__` might be `npm run build:demo`
- pnpm repo: `__INSTALL_COMMAND__` might be `pnpm install --frozen-lockfile`, `__BUILD_COMMAND__` might be `pnpm run build:demo`
- yarn repo: `__INSTALL_COMMAND__` might be `yarn install --frozen-lockfile`, `__BUILD_COMMAND__` might be `yarn build:demo`
-`package.json`
-`pnpm-lock.yaml`
-`package-lock.json`
-`yarn.lock`
-`pnpm-workspace.yaml`
Do not hardcode `pnpm` in the template output unless the repository actually uses `pnpm`.
Also verify the real build entrypoints:
-`package.json` scripts
- existing `build*.sh`
- existing `ci/*.sh`
The template shell script branches on the real files that exist at runtime:
- npm repo: set `__PACKAGE_MANAGER__` to `npm`, `__BUILD_COMMAND__` might be `npm run build:demo`
- pnpm repo with `pnpm-lock.yaml`: set `__PACKAGE_MANAGER__` to `pnpm`, `__BUILD_COMMAND__` might be `pnpm run build:demo`
- pnpm repo without `pnpm-lock.yaml`: still set `__PACKAGE_MANAGER__` to `pnpm`, and let the script fall back to `pnpm install --no-frozen-lockfile`
- yarn repo with `yarn.lock`: set `__PACKAGE_MANAGER__` to `yarn`, `__BUILD_COMMAND__` might be `yarn build:demo`
- yarn repo without `yarn.lock`: let the script fall back to `yarn install`
Do not hardcode `pnpm install --frozen-lockfile` unless the repository actually contains `pnpm-lock.yaml`.
If documentation or copied examples claim `pnpm-lock.yaml` exists but the repository does not contain it, follow the repository state, log the mismatch, and update the docs.
Do not use `npm ci` as the default npm install command in this template.
## Release contract rule
When the target repository is part of the Bingo / SGKT family and no stronger repository-specific contract overrides it, keep these elements together:
If `OSS_DEPLOY_NAME` cannot be confirmed from the current repository, infer it from same-family repositories and mark it in the final explanation as an inferred value that can be adjusted without changing the script structure.
## Prefix design rule
On older GitLab versions, use simple non-overlapping prefixes.
3. Verify whether any copied “项目级说明” block is factual for this repo or only a reusable example; do not assume it is true without checking.
4. Map each environment to a concrete build command.
5. Detect the Node major version from primary evidence and prefer an official `node:X-alpine` image with the matching major version.
6. Decide whether helper scripts under `ci/` reduce repetition.
7. Generate `build_x + release_x` pairs only for active environments.
8. If the user wants one tag to run only one pair, assign unique tag prefixes per pair.
9. Remove paused environments completely, including matching release jobs and documentation references.
10. If the repository or user provides a release snippet, preserve its release image, script signature, uploader contract, and variable names unless explicitly asked to migrate.
11. Validate YAML and shell syntax.
12. Update usage docs if you changed active jobs, file names, or release behavior.
3. Collect release-contract evidence in this order: user-provided CI snippets and variable names, current repository CI and release scripts, organization clues inside the current repository, neighboring same-family repositories in the same workspace, then align the generated result to this skill's fixed OSS release pattern.
4. Explicitly verify whether `package.json`, `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, and `pnpm-workspace.yaml` really exist before deciding how CI installs dependencies.
5. Verify whether any copied “项目级说明” block is factual for this repo or only a reusable example; do not assume it is true without checking.
6. If the repository name, environments, or neighboring projects indicate Bingo, SGKT, `nceduc`, `dhq`, `xinyu`, or `sr`, start from the organization-standard frontend release model instead of a generic template.
7. Map each environment to a concrete build command.
8. Detect the Node major version from primary evidence and prefer an official `node:X-alpine` image with the matching major version.
9. Decide whether helper scripts under `ci/` reduce repetition.
10. Generate `build_x + release_x` pairs only for active environments.
11. If the user wants one tag to run only one pair, assign unique tag prefixes per pair.
12. Remove paused environments completely, including matching release jobs and documentation references.
13. If the repository or user provides a release snippet, preserve its release image, script signature, uploader contract, and variable names unless explicitly asked to migrate.
14. Validate YAML and shell syntax.
15. Update usage docs if you changed active jobs, file names, release behavior, or lockfile assumptions.
## Organization-standard frontend release model
When any of these signals are present, assume the repository belongs to the organization-standard frontend family first:
- Repository or environment names include `sgkt`, `bingo`, `nceduc`, `dhq`, `xinyu`, or `sr`
- The repository uses `springjk/webdev`
- The repository contains multiple `.env.*` files and multiple `build:*` scripts
- The same workspace contains clearly related frontend repositories
If you need per-environment selective triggering on GitLab 11.x, prefer `only: refs + variables` with disjoint prefixes.
...
...
@@ -108,11 +132,14 @@ If the repository has two or more frontend modules, start from `assets/gitlab-mu
Pick the install command from real repository evidence:
-`pnpm install --frozen-lockfile` when the repo actually uses `pnpm`
-`pnpm install --frozen-lockfile` only when the repo actually uses `pnpm` and really contains `pnpm-lock.yaml`
-`pnpm install --no-frozen-lockfile` when the repo uses `pnpm` but `pnpm-lock.yaml` is currently missing
-`npm install` when the repo actually uses `npm`
-`yarn install --frozen-lockfile` when the repo actually uses `yarn`
-`yarn install --frozen-lockfile` when the repo actually uses `yarn` and really contains `yarn.lock`
-`yarn install` when the repo uses `yarn` but `yarn.lock` is currently missing
Do not force `pnpm` because a copied comment block says so if the checked-in repository does not support it.
If copied docs or examples mention `pnpm-lock.yaml` but the repository does not contain it, treat that as a documentation mismatch, follow the repository state, and fix the docs.
Do not use `npm ci` in this skill. For npm-based repositories, use `npm install`.
## Default release script behavior
...
...
@@ -125,8 +152,9 @@ Do not use `npm ci` in this skill. For npm-based repositories, use `npm install`
4. If uploader only accepts directories, copy each zip into a dedicated upload directory.
5. Call the uploader for the dated package and latest package.
Default to OSS-oriented release logic. Only switch to server-directory deployment when the repository already uses that model and the user wants to preserve it.
Default to OSS-oriented release logic in this skill. Do not switch to artifacts-only release.
If the repository or the user already established a release contract such as `springjk/ci-helper:latest` and `OSS_DEPLOY_NAME`, preserve that contract exactly unless the user explicitly requests a migration.
If any evidence establishes the triple `springjk/ci-helper:latest` plus `tags: ["web"]` plus `sh ci/release-dist.sh "$BUILD_TARGET" "$OSS_DEPLOY_NAME"`, keep all three together. Do not downgrade to generic Alpine, omit the `web` runner tag, or replace the script with artifacts-only behavior.
## Common failure patterns
...
...
@@ -166,6 +194,11 @@ Prefer official images such as `node:16-alpine` or `node:24-alpine`, selected fr
Some repositories or runner environments fail on `npm ci` even though `npm install` works normally.
For npm-based repositories in this skill, always use `npm install`.
### `ERR_PNPM_NO_LOCKFILE`
CI used `pnpm install --frozen-lockfile`, but the repository does not actually contain `pnpm-lock.yaml`.
Treat the missing lockfile as the root cause, fall back to `pnpm install --no-frozen-lockfile`, and update the docs so they stop claiming the lockfile exists.
### Uploader says source path not found
The uploader may expect a directory instead of a file.
...
...
@@ -177,6 +210,13 @@ The skill may have simplified release into `artifacts`, a generic Alpine image,
Re-check whether the repository or the user already specified a release image, `oss-deploy`, `OSS_DEPLOY_NAME`, or a fixed `ci/release-dist.sh` call shape.
When those exist, they are not optional hints. Restore them and align every `release_x` job to the same contract.
### Current repo looks blank but same-family repos already use OSS release
Some Bingo or SGKT repositories have incomplete local CI history even though the organization contract is stable in neighboring repositories.
Do not conclude “no OSS contract” from the current repo alone.
Search same-family repositories in the workspace for `springjk/ci-helper:latest`, `tags: [web]`, `OSS_DEPLOY_NAME`, `oss-deploy`, and `ci/release-dist.sh`.
If those neighbors consistently use the organization contract, inherit that contract and mark `OSS_DEPLOY_NAME` mappings as confirmed or inferred in the final explanation.
### UI shows jobs the user no longer wants
Remove the matching `build_x` and `release_x` jobs together.
...
...
@@ -188,7 +228,10 @@ Do not do these unless the user explicitly wants them:
- Do not replace the standard `build_x + release_x` OSS flow with server-directory deployment.
- Do not replace an existing or user-specified OSS release template such as `springjk/ci-helper:latest` plus `sh ci/release-dist.sh "$BUILD_TARGET" "$OSS_DEPLOY_NAME"` with a generic image, `artifacts`, or another release contract.
- Do not preserve only one or two parts of the organization-standard release triple. If `springjk/ci-helper:latest`, `tags: ["web"]`, and `sh ci/release-dist.sh "$BUILD_TARGET" "$OSS_DEPLOY_NAME"` are established, keep all three.
- Do not use custom repository-specific Node images when an official `node:X-alpine` image can be selected from project evidence.
- Do not treat copied “项目级说明” sections as proven facts without checking the repository.
- Do not hardcode `pnpm install --frozen-lockfile` unless `pnpm-lock.yaml` really exists in the repository.
- Do not use `npm ci` as the default npm install command.
- Do not leave only `build_x` without `release_x` when the default OSS release pattern is expected.
- Do not output artifacts-only release from this skill. The fixed mode is `build_x + release_x` plus OSS upload.