{"id":"0b32eee6-4035-45fe-9ae6-7ef2b1a5d675","shortId":"RqzGeH","kind":"skill","title":"gitlab-ci","tagline":"Create and review .gitlab-ci.yml files based on GitLab CI best practices and company standards. Use when creating CI/CD pipelines for new projects, reviewing existing .gitlab-ci.yml, or optimizing pipeline configuration.","description":"# GitLab CI\n\n## Description\n\nCreate and review `.gitlab-ci.yml` files. Based on GitLab CI official best practices, DRY/SSOT design patterns, and company standards.\n\n**Applicable scenarios:**\n\n- Creating `.gitlab-ci.yml` for new projects\n- Reviewing existing `.gitlab-ci.yml`\n- Optimizing CI/CD pipeline performance and maintainability\n\n**Creation mode**: Confirm project tech stack and deployment approach → generate configuration based on rules below → self-check against all rules.\n\n**Review mode**: Read `.gitlab-ci.yml` and files referenced by `include:` → check against rules item by item (annotate ID) → output report:\n\n- **Must Fix**: Violates mandatory rules\n- **Suggested Improvement**: Does not follow best practices\n- **Optional Optimization**: Further optimization opportunity\n\n## Company Standards\n\n### Runner Tag Convention\n\n| Tag | Purpose |\n|-----|------|\n| `sonar-scanner` | General CI tasks |\n\nSet uniformly via `default.tags`:\n\n```yaml\ndefault:\n  tags:\n    - sonar-scanner\n```\n\n### Docker Image Convention\n\nManage image versions uniformly via top-level `variables:`; hard-coding in jobs is prohibited:\n\n```yaml\nvariables:\n  PYTHON_IMAGE: python:3.11-slim\n  NODE_IMAGE: node:20-slim\n  GO_IMAGE: golang:1.22-alpine\n```\n\n### ArgoCD GitOps Integration\n\nCI is only responsible for Build & Test & Publish; deployment is triggered via ArgoCD GitOps:\n\n- CI builds image → pushes to Registry → updates image tag in GitOps repo\n- ArgoCD watches GitOps repo changes → auto-syncs to cluster\n- Preview environments: MR branches auto-create temporary namespaces, destroyed after merge\n\n**Red line**: Directly running `kubectl apply` / `helm install` to production environments from CI is prohibited.\n\n## Rules\n\n### DRY (Don't Repeat Yourself)\n\n**D1: `default:` for shared configuration**\n\n`tags`, `image`, `interruptible`, `retry`, and other cross-job shared configuration must go in `default:`; repeating in each job is prohibited.\n\n**D2: `extends:` to eliminate job duplication**\n\nWhen multiple jobs share the same configuration, extract a hidden job (`.job-name`) as a base class; child jobs inherit via `extends:`.\n\n**D3: YAML anchors to reuse data blocks**\n\nUse YAML anchors (`&anchor` / `*anchor`) for duplicated pure data (such as `rules:` condition lists).\n\n**D4: `!reference` for selective reuse**\n\nWhen only a specific property of a job needs reuse (not the entire job), use `!reference [.job, attribute]`.\n\n### SSOT (Single Source of Truth)\n\n**S1: `include:` to reference shared templates**\n\nCompany-level CI templates must be referenced from `your-org/ci-templates` via `include:project:`; copy-pasting is prohibited:\n\n```yaml\ninclude:\n  - project: your-org/ci-templates\n    ref: main\n    file:\n      - /.gitlab-ci/jobs/mr-doc-check.yml\n```\n\n**S2: `variables:` for centralized mutable values**\n\nImage versions, service names, regions, and other mutable values must be defined as top-level `variables:`; hard-coding in `script:` is prohibited.\n\n**S3: `workflow:rules:` for unified pipeline trigger strategy**\n\nUse `workflow:rules:` at the top of the file to define when to create pipelines, avoiding each job defining redundant trigger conditions separately.\n\n### Structure and Modern Syntax\n\n| ID | Rule | Severity |\n|----|------|--------|\n| R1 | Use `rules:` instead of `only:/except:` (deprecated) | Must Fix |\n| R2 | Use `needs:` to build DAG and reduce pipeline time | Suggested |\n| R3 | Define `workflow:rules:` to avoid duplicate pipelines | Suggested |\n| R4 | `stages:` order is logical (lint → build → test → publish → deploy) | Suggested |\n\n### Reliability\n\n| ID | Rule | Severity |\n|----|------|--------|\n| R5 | All jobs set reasonable `timeout:` | Suggested |\n| R6 | Network-dependent jobs configure `retry:` + `when:` conditions | Suggested |\n| R7 | Non-deployment jobs set `interruptible: true` | Suggested |\n| R8 | Jobs requiring resource cleanup use `after_script:` | Optional |\n\n### Security\n\n| ID | Rule | Severity |\n|----|------|--------|\n| R9 | No hard-coded secrets/credentials in yml | Must Fix |\n| R10 | Sensitive variables use CI/CD Variables (masked + protected) | Must Fix |\n| R11 | Production deployment jobs restricted to `protected` branches/tags | Must Fix |\n\n### Performance\n\n| ID | Rule | Severity |\n|----|------|--------|\n| R12 | `artifacts:` set `expire_in:` to prevent storage bloat | Suggested |\n| R13 | `cache:` configured with correct `key:` and `policy:` | Suggested |\n| R14 | Large test suites use `parallel:` for sharding | Optional |\n| R15 | Deployment jobs use `resource_group:` to prevent concurrent conflicts | Suggested |\n\n## Examples\n\n### Bad\n\n#### 1. Violating DRY — Extensive configuration duplication\n\n```yaml\nbuild-frontend:\n  stage: build\n  image: node:20-slim\n  tags:\n    - sonar-scanner\n  script:\n    - npm ci\n    - npm run build\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n\nbuild-backend:\n  stage: build\n  image: golang:1.22-alpine\n  tags:\n    - sonar-scanner\n  script:\n    - go build ./...\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n\ntest-frontend:\n  stage: test\n  image: node:20-slim\n  tags:\n    - sonar-scanner\n  script:\n    - npm test\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n```\n\n**Issues**: `tags` repeated 3 times (violates D1), `rules` repeated 3 times (violates D3), images hard-coded (violates S2).\n\n#### 2. Deprecated syntax + direct deployment\n\n```yaml\ndeploy:\n  stage: deploy\n  only:\n    - main\n  script:\n    - kubectl apply -f k8s/ --kubeconfig /tmp/kubeconfig\n  variables:\n    IMAGE: registry.example.com/my-service:latest\n```\n\n**Issues**: Uses `only:` deprecated syntax (R1), directly runs `kubectl apply` to the cluster (ArgoCD red line), `latest` tag is not traceable (S2).\n\n#### 3. Copy-paste templates\n\n```yaml\n# Copied lint configuration from another project\nlint:\n  stage: lint\n  image: golangci/golangci-lint:v1.55\n  script:\n    - golangci-lint run\n  tags:\n    - sonar-scanner\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n  allow_failure: true\n  # 30 lines of identical configuration repeated across 5 projects...\n```\n\n**Issues**: Should be extracted to `your-org/ci-templates` (violates S1); cross-project maintenance cost is high, changes require 5 modifications.\n\n### Good\n\n#### 1. DRY + SSOT Standard Approach\n\n```yaml\nvariables:\n  NODE_IMAGE: node:20-slim\n  GO_IMAGE: golang:1.22-alpine\n\ndefault:\n  tags:\n    - sonar-scanner\n  interruptible: true\n  retry:\n    max: 2\n    when:\n      - runner_system_failure\n\nworkflow:\n  rules:\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n    - if: '$CI_COMMIT_BRANCH == \"main\"'\n\n.mr-only:\n  rules: &mr-rules\n    - if: '$CI_PIPELINE_SOURCE == \"merge_request_event\"'\n\ninclude:\n  - project: your-org/ci-templates\n    ref: main\n    file:\n      - /.gitlab-ci/jobs/mr-doc-check.yml\n\nstages:\n  - build\n  - test\n  - publish\n\nbuild-frontend:\n  stage: build\n  image: $NODE_IMAGE\n  rules: *mr-rules\n  script:\n    - npm ci\n    - npm run build\n  artifacts:\n    paths: [dist/]\n    expire_in: 1 day\n\nbuild-backend:\n  stage: build\n  image: $GO_IMAGE\n  rules: *mr-rules\n  script:\n    - go build ./...\n\ntest-frontend:\n  stage: test\n  image: $NODE_IMAGE\n  rules: *mr-rules\n  needs: [build-frontend]\n  script:\n    - npm test\n  coverage: '/coverage: \\d+\\.\\d+%/'\n```\n\n**Strengths**:\n\n- `default:` unifies tags/retry/interruptible (D1)\n- YAML anchor `&mr-rules` reuses trigger conditions (D3)\n- `variables:` manages image versions (S2)\n- `include:` references company templates (S1)\n- `workflow:rules:` unifies trigger strategy (S3)\n- `needs:` accelerates DAG (R2)\n- `artifacts:expire_in:` controls storage (R12)\n\n#### 2. ArgoCD GitOps Integration\n\n```yaml\npublish:\n  stage: publish\n  image: docker:24\n  services:\n    - docker:24-dind\n  script:\n    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .\n    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA\n  rules:\n    - if: '$CI_COMMIT_BRANCH == \"main\"'\n\ngitops-update:\n  stage: deploy\n  image: alpine/git:latest\n  script:\n    - git clone https://gitlab-ci-token:${GITOPS_TOKEN}@gitlab.example.com/your-org/gitops.git\n    - cd gitops/apps/my-service\n    - \"sed -i 's|image:.*|image: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHA}|' values.yaml\"\n    - git commit -am \"chore: update my-service to ${CI_COMMIT_SHA}\"\n    - git push\n  rules:\n    - if: '$CI_COMMIT_BRANCH == \"main\"'\n  resource_group: production\n```\n\n**Strengths**: CI only builds and pushes images; deployment is triggered by updating the GitOps repo for ArgoCD (separation of concerns). `$CI_COMMIT_SHA` ensures image traceability. `resource_group:` prevents concurrent deployments (R15).\n\n## Exemptions\n\n| Scenario | Condition |\n|------|------|\n| Minimal project | Only lint/test with no deployment needs — ArgoCD integration may be omitted |\n| Legacy project migration | `only:/except:` may be temporarily retained during migration; a migration plan is required |\n| One-off scripts | Temporary CI jobs may be simplified; must annotate `# TODO: cleanup` |\n\n## References\n\n- [GitLab CI/CD YAML syntax reference](https://docs.gitlab.com/ee/ci/yaml/)\n- [GitLab CI/CD pipeline efficiency](https://docs.gitlab.com/ee/ci/pipelines/pipeline_efficiency.html)\n- [GitLab CI/CD `rules:` keyword](https://docs.gitlab.com/ee/ci/yaml/#rules)\n- [GitLab CI/CD `needs:` keyword](https://docs.gitlab.com/ee/ci/yaml/#needs)\n- [GitLab CI/CD `include:` keyword](https://docs.gitlab.com/ee/ci/yaml/#include)","tags":["gitlab","enterprise","harness","engineering","addxai","agent-skills","ai-agent","ai-engineering","claude-code","code-review","cursor","devops"],"capabilities":["skill","source-addxai","skill-gitlab-ci","topic-agent-skills","topic-ai-agent","topic-ai-engineering","topic-claude-code","topic-code-review","topic-cursor","topic-devops","topic-enterprise","topic-sre","topic-windsurf"],"categories":["enterprise-harness-engineering"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/addxai/enterprise-harness-engineering/gitlab-ci","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add addxai/enterprise-harness-engineering","source_repo":"https://github.com/addxai/enterprise-harness-engineering","install_from":"skills.sh"}},"qualityScore":"0.458","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 16 github stars · SKILL.md body (9,402 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T01:02:11.710Z","embedding":null,"createdAt":"2026-04-21T19:04:01.235Z","updatedAt":"2026-04-22T01:02:11.710Z","lastSeenAt":"2026-04-22T01:02:11.710Z","tsv":"'/.gitlab-ci/jobs/mr-doc-check.yml':399,911 '/ci-templates':380,395,828,907 '/coverage':976 '/ee/ci/pipelines/pipeline_efficiency.html)':1208 '/ee/ci/yaml/#include)':1229 '/ee/ci/yaml/#needs)':1222 '/ee/ci/yaml/#rules)':1215 '/ee/ci/yaml/)':1201 '/except':474,1167 '/my-service:latest':750 '/tmp/kubeconfig':745 '/your-org/gitops.git':1077 '1':627,843,939 '1.22':184,668,858 '2':728,869,1019 '20':179,641,692,853 '24':1029,1032 '3':712,718,773 '3.11':174 '30':811 '5':818,840 'acceler':1010 'across':817 'allow':808 'alpin':185,669,859 'alpine/git':1064 'anchor':315,322,323,324,985 'annot':106,1190 'anoth':783 'appli':242,741,760 'applic':54 'approach':78,847 'argocd':186,201,215,764,1020,1131,1158 'artifact':587,934,1013 'attribut':356 'auto':221,230 'auto-cr':229 'auto-sync':220 'avoid':453,494 'backend':663,943 'bad':626 'base':9,41,81,306 'best':13,46,120 'bloat':594 'block':319 'branch':228,886,1056,1110 'branches/tags':579 'build':194,204,482,504,635,638,652,662,665,676,913,917,920,933,942,945,955,970,1036,1118 'build-backend':661,941 'build-frontend':634,916,969 'cach':597 'cd':1078 'central':403 'chang':219,838 'check':87,100 'child':308 'chore':1095 'ci':3,12,34,44,138,189,203,249,371,649,655,679,703,802,877,884,896,930,1038,1041,1046,1049,1054,1071,1085,1088,1101,1108,1116,1135,1184 'ci/cd':21,65,566,1195,1203,1210,1217,1224 'class':307 'cleanup':543,1192 'clone':1068 'cluster':224,763 'code':164,425,556,725 'commit':885,1042,1050,1055,1089,1093,1102,1109,1136 'compani':16,52,127,369,1000 'company-level':368 'concern':1134 'concurr':622,1144 'condit':332,459,528,991,1149 'configur':32,80,262,273,296,525,598,631,781,815 'confirm':72 'conflict':623 'control':1016 'convent':131,152 'copi':385,775,779 'copy-past':384,774 'correct':600 'cost':835 'coverag':975 'creat':4,20,36,56,231,451 'creation':70 'cross':270,832 'cross-job':269 'cross-project':831 'd':977,978 'd1':258,715,983 'd2':284 'd3':313,721,992 'd4':334 'dag':483,1011 'data':318,328 'day':940 'default':145,259,277,860,980 'default.tags':143 'defin':417,448,456,490 'depend':523 'deploy':77,197,507,533,574,615,732,734,736,1062,1122,1145,1156 'deprec':475,729,754 'descript':35 'design':49 'destroy':234 'dind':1033 'direct':239,731,757 'dist':936 'docker':150,1028,1031,1035,1044 'docs.gitlab.com':1200,1207,1214,1221,1228 'docs.gitlab.com/ee/ci/pipelines/pipeline_efficiency.html)':1206 'docs.gitlab.com/ee/ci/yaml/#include)':1227 'docs.gitlab.com/ee/ci/yaml/#needs)':1220 'docs.gitlab.com/ee/ci/yaml/#rules)':1213 'docs.gitlab.com/ee/ci/yaml/)':1199 'dri':253,629,844 'dry/ssot':48 'duplic':289,326,495,632 'effici':1205 'elimin':287 'ensur':1138 'entir':351 'environ':226,247 'event':660,684,708,807,882,901 'exampl':625 'exempt':1147 'exist':27,62 'expir':589,937,1014 'extend':285,312 'extens':630 'extract':297,823 'f':742 'failur':809,873 'file':8,40,96,398,446,910 'fix':111,477,561,571,581 'follow':119 'frontend':636,687,918,958,971 'general':137 'generat':79 'git':1067,1092,1104 'gitlab':2,11,33,43,1070,1194,1202,1209,1216,1223 'gitlab-ci':1 'gitlab-ci-token':1069 'gitlab-ci.yml':7,28,39,57,63,94 'gitlab.example.com':1076 'gitlab.example.com/your-org/gitops.git':1075 'gitop':187,202,213,217,1021,1059,1073,1128 'gitops-upd':1058 'gitops/apps/my-service':1079 'go':181,275,675,855,947,954 'golang':183,667,857 'golangci':793 'golangci-lint':792 'golangci/golangci-lint':789 'good':842 'group':619,1113,1142 'hard':163,424,555,724 'hard-cod':162,423,554,723 'helm':243 'hidden':299 'high':837 'id':107,465,510,549,583 'ident':814 'imag':151,154,172,177,182,205,210,264,406,639,666,690,722,747,788,851,856,921,923,946,948,961,963,995,1027,1040,1048,1063,1083,1084,1087,1121,1139 'improv':116 'includ':99,363,382,390,902,998,1225 'inherit':310 'instal':244 'instead':471 'integr':188,1022,1159 'interrupt':265,536,865 'issu':709,751,820 'item':103,105 'job':166,271,281,288,292,300,302,309,346,352,355,455,515,524,534,540,575,616,1185 'job-nam':301 'k8s':743 'key':601 'keyword':1212,1219,1226 'kubeconfig':744 'kubectl':241,740,759 'larg':606 'latest':767,1065 'legaci':1163 'level':160,370,421 'line':238,766,812 'lint':503,780,785,787,794 'lint/test':1153 'list':333 'logic':502 'main':397,738,887,909,1057,1111 'maintain':69 'mainten':834 'manag':153,994 'mandatori':113 'mask':568 'max':868 'may':1160,1168,1186 'merg':236,658,682,706,805,880,899 'migrat':1165,1173,1175 'minim':1150 'mode':71,92 'modern':463 'modif':841 'mr':227,889,893,926,951,966,987 'mr-on':888 'mr-rule':892,925,950,965,986 'multipl':291 'must':110,274,373,415,476,560,570,580,1189 'mutabl':404,413 'my-servic':1097 'name':303,409 'namespac':233 'need':347,480,968,1009,1157,1218 'network':522 'network-depend':521 'new':24,59 'node':176,178,640,691,850,852,922,962 'non':532 'non-deploy':531 'npm':648,650,699,929,931,973 'offici':45 'omit':1162 'one':1180 'one-off':1179 'opportun':126 'optim':30,64,123,125 'option':122,547,613 'order':500 'org':379,394,827,906 'output':108 'parallel':610 'past':386,776 'path':935 'pattern':50 'perform':67,582 'pipelin':22,31,66,435,452,486,496,656,680,704,803,878,897,1204 'plan':1176 'polici':603 'practic':14,47,121 'prevent':592,621,1143 'preview':225 'product':246,573,1114 'prohibit':168,251,283,388,429 'project':25,60,73,383,391,784,819,833,903,1151,1164 'properti':343 'protect':569,578 'publish':196,506,915,1024,1026 'pure':327 'purpos':133 'push':206,1045,1105,1120 'python':171,173 'r1':468,756 'r10':562 'r11':572 'r12':586,1018 'r13':596 'r14':605 'r15':614,1146 'r2':478,1012 'r3':489 'r4':498 'r5':513 'r6':520 'r7':530 'r8':539 'r9':552 'read':93 'reason':517 'red':237,765 'reduc':485 'redund':457 'ref':396,908 'refer':335,354,365,999,1193,1198 'referenc':97,375 'region':410 'registri':208,1039,1047,1086 'registry.example.com':749 'registry.example.com/my-service:latest':748 'reliabl':509 'repeat':256,278,711,717,816 'repo':214,218,1129 'report':109 'request':659,683,707,806,881,900 'requir':541,839,1178 'resourc':542,618,1112,1141 'respons':192 'restrict':576 'retain':1171 'retri':266,526,867 'reus':317,338,348,989 'review':6,26,38,61,91 'rule':83,90,102,114,252,331,432,440,466,470,492,511,550,584,653,677,701,716,800,875,891,894,924,927,949,952,964,967,988,1004,1052,1106,1211 'run':240,651,758,795,932 'runner':129,871 's1':362,830,1002 's2':400,727,772,997 's3':430,1008 'scanner':136,149,646,673,697,799,864 'scenario':55,1148 'script':427,546,647,674,698,739,791,928,953,972,1034,1066,1182 'secrets/credentials':557 'secur':548 'sed':1080 'select':337 'self':86 'self-check':85 'sensit':563 'separ':460,1132 'servic':408,1030,1099 'set':140,516,535,588 'sever':467,512,551,585 'sha':1043,1051,1090,1103,1137 'shard':612 'share':261,272,293,366 'simplifi':1188 'singl':358 'skill' 'skill-gitlab-ci' 'slim':175,180,642,693,854 'sonar':135,148,645,672,696,798,863 'sonar-scann':134,147,644,671,695,797,862 'sourc':359,657,681,705,804,879,898 'source-addxai' 'specif':342 'ssot':357,845 'stack':75 'stage':499,637,664,688,735,786,912,919,944,959,1025,1061 'standard':17,53,128,846 'storag':593,1017 'strategi':437,1007 'strength':979,1115 'structur':461 'suggest':115,488,497,508,519,529,538,595,604,624 'suit':608 'sync':222 'syntax':464,730,755,1197 'system':872 'tag':130,132,146,211,263,643,670,694,710,768,796,861 'tags/retry/interruptible':982 'task':139 'tech':74 'templat':367,372,777,1001 'temporari':232,1183 'temporarili':1170 'test':195,505,607,686,689,700,914,957,960,974 'test-frontend':685,956 'time':487,713,719 'timeout':518 'todo':1191 'token':1072,1074 'top':159,420,443 'top-level':158,419 'topic-agent-skills' 'topic-ai-agent' 'topic-ai-engineering' 'topic-claude-code' 'topic-code-review' 'topic-cursor' 'topic-devops' 'topic-enterprise' 'topic-sre' 'topic-windsurf' 'traceabl':771,1140 'trigger':199,436,458,990,1006,1124 'true':537,810,866 'truth':361 'unifi':434,981,1005 'uniform':141,156 'updat':209,1060,1096,1126 'use':18,320,353,438,469,479,544,565,609,617,752 'v1.55':790 'valu':405,414 'values.yaml':1091 'variabl':161,170,401,422,564,567,746,849,993 'version':155,407,996 'via':142,157,200,311,381 'violat':112,628,714,720,726,829 'watch':216 'workflow':431,439,491,874,1003 'yaml':144,169,314,321,389,633,733,778,848,984,1023,1196 'yml':559 'your-org':377,392,825,904","prices":[{"id":"f90775c4-a83b-4ba0-892f-94bc1fe38d87","listingId":"0b32eee6-4035-45fe-9ae6-7ef2b1a5d675","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"addxai","category":"enterprise-harness-engineering","install_from":"skills.sh"},"createdAt":"2026-04-21T19:04:01.235Z"}],"sources":[{"listingId":"0b32eee6-4035-45fe-9ae6-7ef2b1a5d675","source":"github","sourceId":"addxai/enterprise-harness-engineering/gitlab-ci","sourceUrl":"https://github.com/addxai/enterprise-harness-engineering/tree/main/skills/gitlab-ci","isPrimary":false,"firstSeenAt":"2026-04-21T19:04:01.235Z","lastSeenAt":"2026-04-22T01:02:11.710Z"}],"details":{"listingId":"0b32eee6-4035-45fe-9ae6-7ef2b1a5d675","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"addxai","slug":"gitlab-ci","github":{"repo":"addxai/enterprise-harness-engineering","stars":16,"topics":["agent-skills","ai-agent","ai-engineering","claude-code","code-review","cursor","devops","enterprise","sre","windsurf"],"license":"apache-2.0","html_url":"https://github.com/addxai/enterprise-harness-engineering","pushed_at":"2026-04-17T08:57:37Z","description":"Enterprise-grade AI Agent Skills for software development, DevOps, SRE, security, and product teams. Compatible with Claude Code, Cursor, Windsurf, Gemini CLI, GitHub Copilot, and 30+ AI coding agents.","skill_md_sha":"1a2f729c078b67478d22ea27523f842ca0c46c36","skill_md_path":"skills/gitlab-ci/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/addxai/enterprise-harness-engineering/tree/main/skills/gitlab-ci"},"layout":"multi","source":"github","category":"enterprise-harness-engineering","frontmatter":{"name":"gitlab-ci","description":"Create and review .gitlab-ci.yml files based on GitLab CI best practices and company standards. Use when creating CI/CD pipelines for new projects, reviewing existing .gitlab-ci.yml, or optimizing pipeline configuration."},"skills_sh_url":"https://skills.sh/addxai/enterprise-harness-engineering/gitlab-ci"},"updatedAt":"2026-04-22T01:02:11.710Z"}}