Skip to content

chore(ci): migrate GitHub Actions CI to GitLab CI#2543

Draft
universal-itengineer wants to merge 44 commits into
mainfrom
chore/ci/add-gitlab-ci
Draft

chore(ci): migrate GitHub Actions CI to GitLab CI#2543
universal-itengineer wants to merge 44 commits into
mainfrom
chore/ci/add-gitlab-ci

Conversation

@universal-itengineer

@universal-itengineer universal-itengineer commented Jun 25, 2026

Copy link
Copy Markdown
Member

Description

Migrate the repository CI from GitHub Actions to GitLab CI, following the
approved migration plan in
tmp/ai-summary/gitlab-ci-migration-plan.md.
The root .gitlab-ci.yml is now a thin include-only entrypoint; the real
pipeline lives in .gitlab/ci/**.

What is added

  • .gitlab/ci/ structure: defaults.yml, workflow.yml, stages.yml,
    includes.yml, variables.yml, changelog-sections.txt.
  • .gitlab/ci/jobs/ — job definitions porting the GitHub workflows:
    • build-dev.yml, build-prod.yml, deploy-dev.yml, deploy-prod.yml,
      precache.yml, cleanup.yml.
    • lint-validate.yml (shellcheck, yaml, helm-templates, gens-files,
      gitlab-ci, go), lint-dmt.yml.
    • test.yml, test-scripts-js.yml, test-scripts-python.yml,
      test-d8v-cli.yml.
    • gitleaks.yml, cve-scan.yml (per-MR + daily + manual), svace.yml.
    • auto-assign-author.yml, check-changelog.yml, check-milestone.yml,
      changelog.yml, translate-changelog.yml, backport.yml,
      manual-tools.yml (mrs:summary), release-channels.yml, info.yml.
  • .gitlab/ci/templates/ — reusable hidden templates grouped into
    base/ (build, deploy, info, dual_registry_login), dev/
    (dev, dev_tags, dev_vars, main, release), release/
    (prod_always, prod_manual, prod_vars).
  • .gitlab/ci/scripts/bash/ — shell helpers backing the jobs:
    auto-assign-author.sh, backport.sh, changelog-milestone.sh,
    check-changelog-entry.sh, check-milestone.sh, check-runner-tools.sh,
    gitlab-ci-lint.sh, notify-release-loop.sh, set-vars.sh,
    setup-mr-settings.sh, and lib/api.sh (shared GitLab API helper).
  • .gitlab/ci/scripts/python/changelog_collect.py,
    check_changelog_entry.py.
  • .gitlab/scripts/js/mrs_notifier.mjs (GitLab counterpart of
    prs_notifier.mjs) + mrs_notifier.test.mjs (node:test smoke test) +
    package.json.
  • Runner tag deckhouse is used everywhere; the runner is a shell executor,
    so jobs call check-runner-tools.sh in before_script instead of relying
    on image:.

What is changed

  • Root .gitlab-ci.yml reduced to include: .gitlab/ci/includes.yml.
  • Prod build/deploy: MODULE_EDITION is set per edition via parallel:matrix
    (CE for ce, EE for ee/se-plus/fe); se-plus edition added to the
    build/deploy matrices — matching the GitHub release workflows.
  • release-channels.yml adds a manual Run pipeline flow (prod:* jobs)
    mirroring release_module_release-channels.yml: requirements check, build
    and deploy per edition, version verification matrix, GitLab release
    creation, and Loop notification. The pipeline must run on the tag
    (RELEASE_TAG == CI_COMMIT_TAG, enforced by prod:print-vars).
  • test jobs use a needs: DAG so they run in parallel with lint instead
    of waiting for the whole lint stage.
  • Manual changelog/backport jobs are allow_failure: true so an unplayed
    manual job does not block MR pipelines.
  • svace:set-vars is gated so its MODULES_MODULE_TAG dotenv no longer leaks
    into MR build jobs.
  • lint:shellcheck runs inside a koalaman/shellcheck-alpine:v0.11.0
    container; bash and python helper scripts are scanned.
  • Taskfile.yaml / Taskfile.init.yaml: gohooks task name fix and
    GOTOOLCHAIN=auto so the runner Go toolchain auto-downloads the version
    required by go.mod.
  • images/vm-route-forge: bpf2go regenerated for cilium/ebpf v0.17.1 using
    clang-14 inside a docker image (generated artifacts committed).

What is intentionally NOT migrated (first iteration)

  • e2e workflows (.github/workflows/e2e-*) — out of scope.
  • Reactive slash-commands / webhook listener — GitLab cannot start
    pipelines on MR comments or label changes natively. Manual + scheduled jobs
    cover the same surface; a webhook-listener is tracked as a follow-up.

Why do we need it, and what problem does it solve?

This is preparation for migrating development of the
deckhouse/virtualization module to GitLab. The real CI previously lived in
.github/workflows/; this PR ports it to GitLab CI so the pipeline keeps
working once the repository moves.

What is the expected result?

  1. A push to an MR branch triggers lint:*, test:*, build_dev,
    cve:scan:mr, gitleaks, auto-assign-author, check:milestone,
    check:changelog.
  2. A merge to main/release-* triggers build_dev + deploy_to_dev and
    translate:changelog.
  3. A tag push triggers build_prod / deploy_to_prod_*.
  4. Manual pipelines: backport (TARGET_BRANCH=release-X.Y),
    changelog:milestone (MILESTONE_TITLE=...), mrs:summary,
    prod:* release-channel dispatch (run on the tag with
    RELEASE_TAG/RELEASE_CHANNEL/EDITION_*).
  5. Schedules: cve:scan:daily, svace:*, gitleaks:full:scheduled,
    precache, changelog:*, mrs:summary, cleanup.
  6. task lint / task validation:* green locally; GitLab CI lint green on
    the MR pipeline.

Checklist

  • The code is covered by unit tests.
    • mrs_notifier.test.mjs smoke test added; python scripts covered by
      py_compile smoke check.
  • e2e tests passed.
  • Documentation updated according to the changes.
    • .gitlab/README.md migration log removed; required CI/CD variables are
      documented in the migration plan
      tmp/ai-summary/gitlab-ci-migration-plan.md §4 / §11.13.
  • Changes were tested in the Kubernetes cluster manually.
    • Validated on virt-test: gohooks task name, GOTOOLCHAIN=auto,
      svace tag isolation, shellcheck green via docker image v0.11.0,
      bash/python script split.

Changelog entries

section: ci
type: feature
summary: "Migrate repository CI from GitHub Actions to GitLab CI with full parity: build/deploy (dev/prod, all editions incl. se-plus), lint, tests, secrets/CVE/Svace scanning, changelog/backport automation, MR auto-assign, and manual release-channel dispatch."
impact_level: low

@universal-itengineer universal-itengineer self-assigned this Jun 25, 2026
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
- auto-assign-author: run on every MR event instead of gating on
  changes to the job's own files, so the MR author is actually
  auto-assigned when no assignee is set (the script is idempotent and
  skips when an assignee already exists)
- workflow: skip redundant branch pipelines when an open MR exists
  (CI_OPEN_MERGE_REQUESTS guard) to avoid duplicate branch + MR pipelines
- lint-validate: drop unused RUN_ON_CHANGE matrix var from check:gens-files
  and fold vm-route-forge into the single COMPONENT matrix

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
test:hooks job ran 'task hooks:test' which does not exist (the task is
gohooks:test), matching the migration plan and Taskfile.

lint/test:virtualization-controller jobs failed at 'task virtualization-controller:init'
because runner go (1.25.9, GOTOOLCHAIN=go1.25.9) is older than go.mod's
'go 1.25.11'. Add global GOTOOLCHAIN=auto so the host toolchain
auto-downloads the version required by go.mod, mirroring actions/setup-go@v5.
GitLab CI variables override runner environment variables.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
build_dev pushed tag 'chore_ci_add-gitlab-ci-svace' instead of mr<iid>
because svace:set-vars ran on every MR (no rules) and emitted a dotenv
MODULES_MODULE_TAG=<branch>-svace, and build_dev had no needs: so GitLab's
legacy artifact inheritance loaded that dotenv and overrode .dev's
mr${CI_MERGE_REQUEST_IID} tag.

Add needs: [] to build_dev/build_dev_tags/build_main to opt into DAG mode
with no artifact downloads (their tag/registry vars come from their own
templates). Gate svace:set-vars to the same SVACE_PIPELINE_ENABLED /
schedule / web contexts as svace:build so it no longer runs on ordinary
MR pipelines.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
lint:shellcheck failed on the shell executor because shellcheck is not
preinstalled on the runner host, and check-runner-tools.sh hard-required it.

Add .gitlab/ci/scripts/install-shellcheck.sh which downloads the official
koalaman/shellcheck pre-compiled static binary from GitHub Releases into
~/.local/bin when shellcheck is missing (no-op when already on PATH). This
is distro-agnostic — works on both apt- and rpm-based runners without root.

lint:shellcheck before_script drops shellcheck from the check-runner-tools
guard and runs install-shellcheck.sh instead, so 'task lint:shellcheck' in
script: finds it on PATH (the shell executor shares one bash session between
before_script and script).

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
install-shellcheck.sh failed with HTTP 404: the release asset is named
shellcheck-<version>.linux.<arch>.tar.xz but the URL was missing the
.tar.xz suffix. The inner tarball directory is also shellcheck-<version>
(no arch suffix), so the previous --strip-components path was wrong too.

Append .tar.xz to the URL and extract into a temp dir, then locate the
binary via 'find -name shellcheck' instead of hard-coding the inner
directory name. Verified: curl returns 200, tar extracts the binary.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
task lint:shellcheck runs shellcheck inside the
koalaman/shellcheck-alpine Docker image (Taskfile.yaml), not via a
host-installed binary, so install-shellcheck.sh was dead code — the
v0.11.0 binary it installed was never used.

Remove install-shellcheck.sh and have lint:shellcheck before_script check
for docker instead. The job already ran successfully via the docker image;
this just stops installing an unused binary on every run.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
The lint:shellcheck task only scanned a hardcoded list of 5 paths and
missed .gitlab/ci/scripts entirely, and produced no output when clean,
so a passing job looked like nothing was checked.

Collect files via 'find .gitlab/ci/scripts -type f -name *.sh' (whole
tree, recursive) plus the existing explicit list, and log the file count,
the file list, and a 'no issues found' footer. Use find instead of **
glob so it works under plain sh (task default shell, no globstar).

Fix SC1091 in the 5 scripts that source lib/api.sh by making the
'# shellcheck source=' directives repo-root-relative so shellcheck follows
them. Suppress SC2154 for CI_* / GITLAB_API_TOKEN (runtime-injected by the
GitLab Runner) with a file-level disable + explanation.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
v0.11.0 is the latest stable ShellCheck release (2025-08-04), available as
the koalaman/shellcheck-alpine:v0.11.0 Docker Hub tag. Pin the version tag
for reproducibility.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
The .gitlab/ci/scripts directory mixed .sh and .py files together. Split
into language-specific subfolders:

  .gitlab/ci/scripts/bash/    .sh wrappers + lib/api.sh
  .gitlab/ci/scripts/python/  .py scripts

Update all references: job/template YAML invocations, the shellcheck source=
directives, the wrapper -> python path resolution (/../python/),
and the README tree.

Taskfile lint:shellcheck now points directly at .gitlab/ci/scripts/bash/
(and bash/lib/) instead of scanning the whole scripts tree with find, since
the bash scripts live in their own folder now.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…o lint:go

Fixes two failing GitLab CI jobs and restores the lost "lint all Go
modules" step from the GitHub Actions migration:

- lint:helm-templates: install helm v3 and jq as portable prebuilt
  binaries in before_script (arch-aware, no sudo) instead of relying on
  the runner host; require docker/git/curl/python3 for kubeconform.sh.
  HELM_VERSION=3.16.3 and JQ_VERSION=1.7.1 added to variables.yml.
  kubeconform.sh itself is untouched.

- lint:go: new job in lint-validate.yml, direct migration of the GH
  lint_go job from dev_module_build.yml. Installs the pinned prebuilt
  golangci-lint v${GOLANGCI_LINT_VERSION} via install.sh (fixes the
  flaky install.sh-latest checksum failure) and runs golangci-lint run
  in every directory shipping a .golangci.yaml, pruning the same
  upstream modules as GH (images/cdi-cloner/cloner-startup,
  images/dvcr-artifact, test/performance/shatal).

- Remove the redundant single-dir lint:virtualization-controller job
  from test.yml (now covered by lint:go).

- Taskfile.init.yaml: bump golangci-lint install from v1.64.8 to v2.11.1
  via the v2 module path, aligning with GOLANGCI_LINT_VERSION and the
  v2-format .golangci.yaml configs in every subproject.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Three matrix legs of check:gens-files failed on the GitLab shell runner:

- virtualization-artifact: go generate needs the moq binary. "go install
  tool" puts it in $(go env GOPATH)/bin, which the shell runner does not
  add to PATH (GitHub setup-go@v5 did this automatically). Export PATH
  with GOPATH/bin so //go:generate moq resolves.

- vm-route-forge: bpf2go (go tool github.com/cilium/ebpf/cmd/bpf2go)
  shells out to clang and llvm-strip, which are absent on the runner.
  Install the same apt packages as the GH workflow dev_validation.yaml
  (llvm, linux-headers, clang, libbpf-dev, uuid-runtime, gcc-multilib),
  guarded by command presence checks and sudo -n to fail fast instead of
  hanging on a password prompt.

- api: "task generate" is defined in api/Taskfile.dist.yaml, not the
  root Taskfile, so it must run from inside api/ (mirrors the GH job
  which does cd ./api first). Run it as cd api && go install tool &&
  task generate.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
The vm-route-forge leg of check:gens-files needs clang, llvm-strip and
the libbpf/kernel headers to run bpf2go (go tool
github.com/cilium/ebpf/cmd/bpf2go). The GitLab shell runner runs as the
gitlab-runner user, which has no passwordless sudo, so the apt-get
install used by the GitHub workflow fails with "sudo: a password is
required".

Run the generation inside the public ghcr.io/cilium/ebpf-builder image
instead, bind-mounting the repo at /src. The image ships clang-22,
llvm-strip-22, libbpf-dev and linux headers. Point bpf2go at the
versioned binaries via BPF2GO_CC/BPF2GO_STRIP (the image has no bare
clang/llvm-strip), and add -I/usr/include/x86_64-linux-gnu via
BPF2GO_CFLAGS so <asm/ptrace.h> resolves (the image symlinks
/usr/include/asm to asm-generic, which lacks ptrace.h).

Added docker to check-runner-tools for the check:gens-files matrix job,
since the vm-route-forge leg now requires it.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Switch the bpf2go generation inside ghcr.io/cilium/ebpf-builder from
clang-22 to clang-14, matching the toolchain that produced the committed
ebpf_x86_bpfel.{go,o} files (GitHub ran on ubuntu-22.04 where
`apt-get install clang` pulls clang-14). The image ships clang-14/17/22,
so only the BPF2GO_CC/BPF2GO_STRIP env vars change.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
… v0.17.1

The committed ebpf_x86_bpfel.{go,o} were generated with cilium/ebpf
v0.16.0, but go.mod was bumped to v0.17.1 without regenerating. bpf2go
v0.17.1 emits ebpfVariableSpecs/ebpfVariables for the `unused` const
variable (used in route_watcher.c to force the route_event struct into
the ELF), so the regenerated output adds those types. go build ./...
passes against the new files.

Regenerated with clang-14 + llvm-strip-14 inside
ghcr.io/cilium/ebpf-builder (BPF2GO_CFLAGS=-I/usr/include/x86_64-linux-gnu).

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
The deckhouse runner tag is confirmed as registered for the project.
Remove all TODO_RUNNER_TAG placeholder comments across the .gitlab/
migration artifacts and rewrite README §6 / §10 to describe the tag as
confirmed instead of a placeholder.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…fig, fix changelog yml schema

- build_dev/build_dev_tags/build_main: add set_vars job in info stage that
  derives MODULE_EDITION (edition/ce label), DEBUG_COMPONENT (first delve/*
  label), RELEASE_IN_DEV from MR labels; consume its dotenv via needs and set
  WERF_VIRTUAL_MERGE=0, matching the GitHub dev_setup_build behavior. set-vars.sh
  is now wired in (dead code removed); MODULES_MODULE_TAG stays per-template.
- cleanup: pass --config werf_cleanup.yaml and compose --repo from
  MODULES_MODULE_SOURCE/MODULES_MODULE_NAME (via .dev_vars) instead of
  hardcoding the path, restoring the GitHub retention behavior.
- changelog_collect.py: render_yaml now emits the deckhouse CHANGELOG schema
  (sections -> features/fixes -> summary + pull_request), validated against
  existing CHANGELOG-*.yml; strip :low section suffix.
- check_changelog_entry.py & changelog_collect.py: narrow ALLOWED_TYPES to
  {feature, fix} (deckhouse/changelog-action only renders features/fixes),
  with a clear error for unsupported types.

Refs: virtualization-m9e.5.1, virtualization-m9e.5.2, virtualization-m9e.5.3, virtualization-m9e.5.4
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…dd CVE per-MR scan, cleanup

- translate:changelog: override script with EN->RU implementation (upstream template
  is hardcoded RU->EN), add rules for push to main/release-X.Y, fix header comment.
- cve-scan: add cve:scan:mr (MR-gated, needs build_dev); document VAULT_ROLE as
  required Project CI/CD var in variables.yml; drop redundant CUSTOM_PATH vars.
- lint:go: remove dead prune entry for ./test/performance/shatal (path never existed;
  real module test/performance/tools/shatal is intentionally linted).
- changelog_collect.py: move MR-body temp file out of CHANGELOG/ to project root so
  git add CHANGELOG/ cannot stage it.
- dev_vars/prod_vars: remove unused FALLBACK_* vars.
- Port dropped GH jobs: lint:dmt (allow_failure), test:scripts:js (fix package.json
  + add mrs_notifier.test.mjs smoke test), test:scripts:python (py_compile smoke),
  test:build:d8v-cli (build + --help). All wired into includes.yml.
- README: document port/drop decisions, CVE scan jobs, VAULT_ROLE/RELEASE_TOKEN,
  merge translate-changelog and CVE snippets.

Refs: virtualization-m9e.5.5, virtualization-m9e.5.6, virtualization-m9e.5.7, virtualization-m9e.5.8, virtualization-m9e.5.9
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
m9e.6.1 (bug): build_prod/deploy_to_prod_* set MODULE_EDITION per edition
via parallel:matrix (CE for ce, EE for ee/se-plus/fe), matching the GitHub
release_module_build-and-registration.yml. .werf/consts.yaml defaults
MODULE_EDITION to EE and uses it as a Go build tag + EE-only image gate,
so without this the ce prod image was built as EE. .prod_vars intentionally
does not set it (the matrix provides it).

m9e.6.2: add se-plus (path se-plus/modules, MODULE_EDITION=EE) to the
build_prod and deploy_to_prod_* matrices. GitLab runs all four editions in
parallel; GH runs se-plus/fe after ee (needs: ee) — acceptable since each
edition builds into its own registry subpath with no shared artifact.

m9e.6.3: port the release_module_release-channels.yml flow to
.gitlab/ci/jobs/release-channels.yml as a manual Run-pipeline flow
(prod:* jobs, CI_PIPELINE_SOURCE == web, never collides with the tag-push
chain). Adds: RELEASE_CHANNEL/RELEASE_TAG/EDITION_CE/EDITION_EE/
ENABLE_BUILD/CHECK_ONLY/SKIP_REQUIREMENTS_CHECK/RELEASE_TO_GITLAB/
SEND_RESULTS_TO_LOOP inputs, prod:check-requirements, per-edition build/deploy
(se-plus/fe needs prod:build:ee), prod:check-version matrix
(registry/releases/documentation via tools/moduleversions),
prod:create-gitlab-release (GitLab Releases from the merged changelog MR,
was create-github-release), prod:notify-loop (status table to Loop).
New .prod_read_registry template + prod_check/prod_deploy/prod_verify/
prod_release stages. Documented deviations: GitLab Releases instead of
GitHub Releases; pipeline must run on the tag (RELEASE_TAG == CI_COMMIT_TAG,
enforced) because GitLab cannot checkout an arbitrary tag without overriding
the inherited werf Setup before_script; resource_group replaces GH
cancel-in-progress concurrency.

README updated (§7 jobs table, §8 manual pipelines, §10 known TODOs).

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
… jobs

GitLab CI lint rejects a hard 'needs' on a job (prod:check-requirements)
that can be absent from the pipeline (its rule gates it out when
CHECK_ONLY or SKIP_REQUIREMENTS_CHECK or no edition selected). Mark the
need optional on prod:build:ce/ee so the DAG validates in all dispatch
modes.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
prod:build:* (stage build) needs prod:check-requirements (stage prod_check),
so prod_check must precede build in the stages list, otherwise GitLab CI
lint rejects the need as 'not defined in current or prior stages'.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…ailures

lint:dmt failed: no license header in gitlab-ci-lint.sh and set-vars.sh.
lint:yaml (prettier) failed: info.yml and translate-changelog.yml had
single-quote if-rules prettier wants double-quoted. Both are pre-existing
migration files now blocking CI.

- task dev:addlicense on .gitlab/ci/scripts/bash (added headers to the 2
  scripts; all others already had them).
- prettier -w on the 2 yaml jobs (single if-rule quote style each).

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…-* branches

Add a release-* branch rule (CI_COMMIT_BRANCH =~ /^release-/) to the four
lint jobs that previously only had a 'main' rule:
  lint:yaml, lint:helm-templates, check:gens-files, lint:gitlab-ci.

This makes lint coverage on release-branch pipelines consistent with main
and with no-cyrillic/doc-changes/shellcheck/go, which already ran on
release-* branches. rules:changes semantics on branch pushes are
identical to main (compares against the previous SHA on the branch), so
mirroring the main rule is safe.

Closes sub-item of virtualization-m9e.5.18.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
The deckhouse shell runner host has no node/npm installed, so the job
failed at check-runner-tools.sh. Run npm install + npm test inside the
official node:${NODE_VERSION} image via docker run, mirroring how
check:gens-files runs the vm-route-forge leg in a container. The repo is
bind-mounted at /src.

Add NODE_VERSION=24 to variables.yml, matching the GH workflow
test_scripts_js env.

Closes virtualization-m9e.5.19.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…ollution

test:scripts:js ran 'docker run node:24 ... npm install' as root (default
uid). node_modules/ and package-lock.json were created root-owned in the
shared shell-executor workspace and not cleaned between jobs. The next
checkout (git clean/checkout) in gitleaks:diff could not remove them
('Permission denied'), failing 'Getting source from Git repository'
before the gitleaks script ever ran, so gitleaks.json was never produced
('no matching files' / 'Job failed: exit status 1').

Run npm under the host runner-user uid/gid (-u $(id -u):$(id -g)) with
HOME=/tmp and --cache /tmp/.npm so generated files are runner-user owned
and git can clean them on the next checkout.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…lution

Previous fix (-u runner-user) still left node_modules/package-lock.json in
the shared shell-executor workspace. The real issue is deeper: root-owned
leftovers from pre-fix runs already on the runner cannot be removed by
runner-user, so git clean on the NEXT job's 'Getting source from Git
repository' step fails with 'Permission denied' and breaks unrelated jobs
(show_dev_manifest, test:build:d8v-cli, gitleaks:diff, ...) before their
script runs.

Mount the repo READ-ONLY and copy the JS sources to an ephemeral tmpdir
inside the container where npm install/npm test run. node_modules and
package-lock.json now never touch the workspace at all, so no job can be
broken by leftover files regardless of who owned them.

One-time manual cleanup of existing root-owned leftovers on runner
H61TLxhnT is still required (sudo rm -rf .../virt-test/.gitlab/scripts/js/
{node_modules,package-lock.json}); no CI-only fix can remove root-owned
files because the checkout that would run before any cleanup script
already fails on them.

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Collapse the five separate deploy_prod_alpha..rock_solid stages into one
deploy_prod stage and make the per-channel prod deploys independent
when:manual jobs (each needs:[build_prod] only) instead of a forced
alpha->beta->ea->stable->rock-solid promotion chain. This matches GitHub
release_module_release-channels.yml channel-pick semantics and removes a
carried-over artifact of the old root .gitlab-ci.yml.

The web Run-pipeline prod:deploy:* jobs (release-channels.yml) move from
the prod_deploy stage to the same deploy_prod stage, unifying both prod
deploy flows under one stage.

Drop the dead gitleaks stage (every active gitleaks job runs in scan).
The disabled upstream gitleaks_* override jobs get stage:scan so nothing
references the removed stage at config-parse time.

Refs: virtualization-m9e.5.21
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
…deploy

The "local" prefix was uninformative and conceptually clashed with
`include: local:`. These are base templates meant to be extended by the
concrete build/deploy jobs, so `.base_build` / `.base_deploy` state intent.

Renames the two anchors (templates/build.yml, templates/deploy.yml) and all
20 `extends:` references across build-dev, build-prod, precache, svace,
release-channels, deploy-dev, deploy-prod, plus comments and includes.yml.
No behavior change: the single `build` stage stays (dev and release builds
are already separated by rules, never co-run in one pipeline).

Refs: virtualization-m9e.5.21
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Regroup .gitlab/ci/templates by the two global processes plus shared base:
  base/    build.yml deploy.yml dual_registry_login.yml info.yml
  dev/     dev.yml dev_tags.yml main.yml release.yml dev_vars.yml
  release/ prod_always.yml prod_manual.yml prod_vars.yml

Only include: local: paths in includes.yml change. Anchor names are
unchanged (.base_build, .dev, .prod_vars, ...), so no job extends: edits
are needed. No rules/stage/behavior change.

Refs: virtualization-m9e.5.22
Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
Remove the migration-progress README that tracked the GitLab CI migration.
It was the source of TODO comments scattered across CI files; the migration
log now lives in the migration plan (tmp/ai-summary/gitlab-ci-migration-plan.md)
and the archived copy is preserved in bd issue virtualization-m9e.8.

Clean up every reference to .gitlab/README.md in:
- .gitlab-ci.yml
- .gitlab/ci/variables.yml
- .gitlab/ci/templates/dev/dev_vars.yml
- .gitlab/ci/jobs/changelog.yml
- .gitlab/ci/jobs/manual-tools.yml
- .gitlab/ci/jobs/lint-dmt.yml
- .gitlab/ci/jobs/svace.yml

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
@universal-itengineer universal-itengineer changed the title Chore/ci/add gitlab ci chore(ci): migrate GitHub Actions CI to GitLab CI Jun 25, 2026
Remove internal tracker (bd/beads) issue IDs scattered in comments across
.gitlab/ci files so they do not leak into the public PR. No behavior change.

Affected files:
- .gitlab/ci/stages.yml
- .gitlab/ci/includes.yml
- .gitlab/ci/templates/release/prod_manual.yml
- .gitlab/ci/jobs/deploy-prod.yml
- .gitlab/ci/jobs/gitleaks.yml

Signed-off-by: Nikita Korolev <nikita.korolev@flant.com>
@universal-itengineer universal-itengineer added this to the v1.10.0 milestone Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant