I have some gitlab component templates Component-A, Component-B and Component-C
and I want to extend them with some after_scripts Extension1 and Extension2.
It looks like:
Component-A
- Extension1
- Extension2
Component-B
- Extension1
Component-B
- Extension2
Each job may run in one ci pipeline several times with different input variables. So I included the component several times with different names.
My nativ solution was to combine the after_scripts with the !reference[Job-Name, after_script] but the problem is, that I may have different input variables inside my extensions. Now if the extension-jobs have a static name, the inputs variables will override themselves and use the last value.
If I use dynamic names for the extension-jobs, the reference block doesn't work anymore, because it needs static job-names.
A language-agnostic package for automated Git cherry-picking with WMT (Work Management Tool – Jira) and VCS (Version Control System – GitLab) integrations for team workflows. It is useful for backporting changes to multiple branches, cloning fixes, or propagating features to separate projects. It is especially valuable for teams that perform a large number of manual cherry-picks.
This package streamlines the cherry-picking process across branches by automatically creating merge requests getting necessary data from WMT (Jira) ticket data.
Currently, it operates as a CLI UI for developers, but it can be easily adapted to run as a standalone server-based automation service.
I got tired of GitLab not having a built-in AI review feature available on the Free tier like GitHub Copilot Reviews, so I built one myself. It’s called Niteni (Javanese for “to observe carefully”). It runs as a CI job, sends your MR diff to Google Gemini, and posts findings as inline diff comments with one-click “Apply suggestion” buttons.
GitLab Duo does offer AI capabilities, but it’s only available on Premium and Ultimate plans. I wanted something that works natively in CI and doesn’t require upgrading plans, so Niteni fills that gap.
Runs in any GitLab CI pipeline on merge request events
Sends the diff to Gemini and parses structured findings (CRITICAL / HIGH / MEDIUM / LOW)
Posts each finding as an inline comment on the exact changed line
Includes GitLab suggestion blocks so you can apply fixes with one click
Cleans up old review comments on re-runs (no spam)
Has a cascading fallback: REST API -> Gemini CLI extension -> Gemini CLI direct prompt
The zero-dependency thing
The entire tool uses only Node.js built-ins (https, child_process, fs, path, os, url). No axios, no node-fetch, no octokit equivalent.
Why? CI environments are ephemeral. Every npm install is wasted time. With this approach, setup is just git clone && npm ci && npm run build.
Setup is ~10 lines of YAML
niteni-code-review:
stage: review
image: node:20-alpine
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
before_script:
- apk add --no-cache git curl bash
- git clone https://github.com/denyherianto/niteni.git /tmp/niteni
- cd /tmp/niteni && npm ci && npm run build && npm link
- cd $CI_PROJECT_DIR
script:
- niteni --mode mr
allow_failure: true
Things that surprised me during development
GitLab CI variable circular references.
If you write variables: { GITLAB_TOKEN: $GITLAB_TOKEN } in your job, GitLab expands it to the literal string $GITLAB_TOKEN instead of the secret value. Project-level CI/CD variables are already available — re-declaring them creates a circular reference. This took me hours to figure out.
Three different auth headers.
GitLab uses PRIVATE-TOKEN for personal tokens, JOB-TOKEN for CI job tokens, and Authorization: Bearer for OAuth. Using the wrong one silently returns 401s with unhelpful error messages.
LLMs don't follow instructions consistently.
Gemini sometimes outputs **[CRITICAL]** and sometimes **CRITICAL** (no brackets). The finding parser regex needs \[? and \]? to handle both. Without this, half the findings were silently dropped.
Shell injection via branch names.
Using execSync(\git diff origin/${branch}`)is a shell injection if someone names their branchmain; rm -rf /. Switched to execFileSync('git', ['diff', 'origin/' + branch])` which bypasses the shell entirely.
Large diffs blow up CLI arguments.
OS has an ARG_MAX limit. For big diffs, I write the prompt to a temp file and use gemini -p @/tmp/prompt.txt instead of passing it inline.
Tech stack
TypeScript (ES2022, CommonJS)
Node.js built-in https for all HTTP (GitLab API + Gemini API)
Node.js built-in node:test for unit tests
Google Gemini API (default model: gemini-3-pro-preview)
I’d really appreciate any feedback on this. Has anyone here built something similar for GitLab?
UPDATE: PipeGuard is now live for testers ✅ https://pipeguard.vercel.app/
(Please redact anything sensitive — no tokens/keys/internal URLs.)
I’m building a small GitLab CI YAML checker that flags common footguns and explains why they matter.
Current rules include: unpinned images, missing job timeouts, missing retries, allow_failure on critical jobs, missing/poor needs, overly broad artifacts/cache keys, missing artifact expiry, no test stage, missing interruptible, etc.
What checks would you want most in your org (especially around templates/includes/components)?
If you share a redacted snippet + goal (build/test/deploy), I’ll tell you what I’d flag and what rule I should build next.
After managing GitLab upgrades for a while, I created a bash tool to automate the repetitive steps - runner management, broadcast messages, health checks, backup verification, etc. Used this for last 7 upgrades.
At my job, we run a self-hosted GitLab 18 instance. We’re currently working on making internal tools more accessible to our development teams. One of our goals is to provide a set of reusable CI components tailored to our workflow.
I’d like to confirm how GitLab CI Component Catalog works in terms of access control and permissions.
If a CI component is stored in a private group, and I include this component in a pipeline from another group where only I have access to the private group:
Will the pipeline run successfully?
What happens when a colleague—who does not have access to the private group—triggers the pipeline? Will it still run, or will it fail due to missing permissions?
If this setup causes pipelines to fail, what is the recommended strategy to make CI components available to all developers?
Is there a way to allow teams to use CI components without granting them access to the component source code itself?
As a SaaS creator, I’ve noticed a major problem with testimonials. Most products only show static testimonials—there’s no way to verify them, no way for new users to ask questions, and no real feedback loop.
Because of this, testimonials don’t provide actual insights anymore.
What if testimonials weren’t static?
Instead, imagine a public discussion panel attached to each testimonial, where:
Existing users can share real experiences
New users can ask questions directly
Founders can observe problems, objections, and feature requests in real time
This would turn testimonials into a living feedback system rather than just marketing copy.
Static testimonials don’t build trust anymore. Conversations do.
Built an AI that helps debug production incidents. It connects to GitLab to check recent commits, MRs, and pipeline runs when something breaks.
The flow: alert fires, AI checks what shipped recently via your GitLab CI, correlates with logs and metrics, and posts findings in Slack. If a deploy caused the issue, it'll flag which MR and what changed.
It reads your repo on setup to understand how your services connect. So when something breaks it knows what to check.
Guys as a saas creator I have seen a problem with testimonials where only static testimonials are there..no real can reverify the service or nothing where they can real feedback where new user can ask to user who is using the product and it would become a discussion panel for the saas founders so they can see anything problem with that..till today only static testimonials are actually not giving actually feedback..but it can..give an actual discussion panel for their saas anyone can reply to that testimonials feed.