{"id":49537,"date":"2025-05-28T06:36:31","date_gmt":"2025-05-28T06:36:31","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=49537"},"modified":"2025-05-28T08:45:49","modified_gmt":"2025-05-28T08:45:49","slug":"gitlab-top-30-gitlab-pipeline-automation-questions-answers","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/gitlab-top-30-gitlab-pipeline-automation-questions-answers\/","title":{"rendered":"Gitlab  &#8211; Top 30 GitLab Pipeline Automation FAQ"},"content":{"rendered":"\n<p>Here&#8217;s a curated set of <strong>30 most frequently asked real-world questions<\/strong> about <strong>GitLab CI\/CD pipeline automation<\/strong>, with clear and concise answers \u2014 perfect for training sessions or real-world use:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 <strong>Top 30 GitLab Pipeline Automation Questions &amp; Answers<\/strong><\/h3>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">1. <strong>What is the difference between <code>needs<\/code> and <code>dependencies<\/code> in GitLab CI?<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>needs<\/code>: Controls execution order (jobs run as soon as dependencies finish), enables parallelism.<\/li>\n\n\n\n<li><code>dependencies<\/code>: Controls artifact download but doesn\u2019t affect execution order.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">2. <strong>Can a single job be reused in multiple stages?<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No, a job can only belong to one stage. You can replicate logic using YAML anchors or templates.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">3. <strong>How to conditionally run a job only for merge requests?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">rules:\n  - <span class=\"hljs-keyword\">if<\/span>: <span class=\"hljs-string\">'$CI_PIPELINE_SOURCE == \"merge_request_event\"'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">4. <strong>How to run jobs only on a specific branch like <code>main<\/code> or <code>dev<\/code>?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">only:\n  - main\n<\/code><\/span><\/pre>\n\n\n<p>Or use:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">rules:\n  - <span class=\"hljs-keyword\">if<\/span>: <span class=\"hljs-string\">'$CI_COMMIT_BRANCH == \"main\"'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">5. <strong>How to cache dependencies between jobs?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">cache:\n  paths:\n    - node_modules\/\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">6. <strong>How to share artifacts between jobs?<\/strong><\/h4>\n\n\n\n<p>Use <code>artifacts<\/code> and <code>dependencies<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">job1<\/span>:\n  <span class=\"hljs-selector-tag\">script<\/span>: <span class=\"hljs-selector-tag\">make<\/span> <span class=\"hljs-selector-tag\">build<\/span>\n  <span class=\"hljs-selector-tag\">artifacts<\/span>:\n    <span class=\"hljs-selector-tag\">paths<\/span>: <span class=\"hljs-selector-attr\">&#91;build\/]<\/span>\n\n<span class=\"hljs-selector-tag\">job2<\/span>:\n  <span class=\"hljs-selector-tag\">script<\/span>: <span class=\"hljs-selector-tag\">deploy<\/span>\n  <span class=\"hljs-selector-tag\">dependencies<\/span>: <span class=\"hljs-selector-attr\">&#91;job1]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">7. <strong>How to trigger another project\u2019s pipeline?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">trigger:\n  project: my-group\/another-project\n  branch: main\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">8. <strong>How to create a manual approval job in a pipeline?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">when<\/span>: manual\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">9. <strong>How to run a job only when a tag is pushed?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">only:\n  - tags\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">10. <strong>Can we define multiple <code>.gitlab-ci.yml<\/code> files?<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Yes, use the <code>include:<\/code> keyword to import local, remote, or project-specific YAML files.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">11. <strong>How to define environment-specific jobs (dev, staging, prod)?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">rules:\n  - <span class=\"hljs-keyword\">if<\/span>: <span class=\"hljs-string\">'$CI_ENVIRONMENT_NAME == \"staging\"'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">12. <strong>How to use custom variables in GitLab CI?<\/strong><\/h4>\n\n\n\n<p>Define in UI or <code>.gitlab-ci.yml<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">variables:\n  DEPLOY_ENV: <span class=\"hljs-string\">\"prod\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">13. <strong>How to use matrix builds in GitLab?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">parallel<\/span>:\n  <span class=\"hljs-selector-tag\">matrix<\/span>:\n    <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">VARIANT<\/span>: <span class=\"hljs-selector-attr\">&#91;debug, release]<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">14. <strong>How to run a job only if certain files changed?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">rules<\/span>:\n  <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">changes<\/span>:\n      <span class=\"hljs-selector-tag\">-<\/span> <span class=\"hljs-selector-tag\">src<\/span><span class=\"hljs-comment\">\/**\/<\/span>*\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">15. <strong>How to skip pipeline for a commit?<\/strong><\/h4>\n\n\n\n<p>Use <code>[ci skip]<\/code> in commit message.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">16. <strong>What is <code>allow_failure: true<\/code> used for?<\/strong><\/h4>\n\n\n\n<p>It lets a job fail without failing the whole pipeline.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">17. <strong>How to handle secrets or credentials securely?<\/strong><\/h4>\n\n\n\n<p>Store them as CI\/CD variables in GitLab UI (masked and protected if needed).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">18. <strong>What is the purpose of <code>before_script<\/code> and <code>after_script<\/code>?<\/strong><\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>before_script<\/code>: runs before the main job script.<\/li>\n\n\n\n<li><code>after_script<\/code>: runs after the main job script (even on failure).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">19. <strong>How to make a job retry on failure?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">retry<\/span>: 2\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">20. <strong>What is <code>artifacts:expire_in<\/code> used for?<\/strong><\/h4>\n\n\n\n<p>Sets how long GitLab retains the artifact:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">artifacts:\n  expire_in: 1 week\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">21. <strong>What is the role of <code>stages<\/code> in GitLab CI?<\/strong><\/h4>\n\n\n\n<p>Defines the pipeline flow. Jobs in the same stage run in parallel; stages run sequentially.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">22. <strong>How to conditionally run a job on a variable value?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">rules:\n  - <span class=\"hljs-keyword\">if<\/span>: <span class=\"hljs-string\">'$DEPLOY_ENV == \"prod\"'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">23. <strong>How to disable a job temporarily?<\/strong><\/h4>\n\n\n\n<p>Add:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">when<\/span>: never\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">24. <strong>How to run a job only when another job fails?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">when<\/span>: on_failure\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">25. <strong>How to visualize job dependencies (DAG)?<\/strong><\/h4>\n\n\n\n<p>Use <code>needs:<\/code> to define dependencies and GitLab will show it in pipeline graph view.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">26. <strong>Can you trigger child pipelines?<\/strong><\/h4>\n\n\n\n<p>Yes, using:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">trigger<\/span>:\n  <span class=\"hljs-selector-tag\">include<\/span>: <span class=\"hljs-selector-tag\">child-pipeline<\/span><span class=\"hljs-selector-class\">.yml<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">27. <strong>How to control concurrency in pipelines?<\/strong><\/h4>\n\n\n\n<p>Use <code>resource_group:<\/code> to ensure mutual exclusion:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">resource_group<\/span>: deploy-prod\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">28. <strong>How to limit job execution time?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">timeout<\/span>: 15 minutes\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">29. <strong>How to use GitLab CI templates (SAST, DAST, etc.)?<\/strong><\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">include<\/span>:\n  - template: Security\/SAST.gitlab-ci.yml\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">30. <strong>How to pass data between jobs?<\/strong><\/h4>\n\n\n\n<p>Use:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>artifacts<\/code> (for file data)<\/li>\n\n\n\n<li><code>cache<\/code> (for shared folders)<\/li>\n\n\n\n<li><code>CI\/CD variables<\/code> (for text\/values)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">31 To copy <strong>artifacts from two separate jobs into a single common directory<\/strong>, you need to follow these steps in GitLab CI\/CD:<\/h2>\n\n\n\n<p>Combine artifacts from <code>job1<\/code> and <code>job2<\/code> into a common directory in <code>job3<\/code>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">stages:\n  - build\n  - merge\n\njob1:\n  stage: build\n  script:\n    - <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Job 1 output\"<\/span> &gt; job1.txt\n  artifacts:\n    paths:\n      - job1.txt\n\njob2:\n  stage: build\n  script:\n    - <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Job 2 output\"<\/span> &gt; job2.txt\n  artifacts:\n    paths:\n      - job2.txt\n\njob3:\n  stage: merge\n  needs:\n    - job: job1\n      artifacts: <span class=\"hljs-keyword\">true<\/span>\n    - job: job2\n      artifacts: <span class=\"hljs-keyword\">true<\/span>\n  script:\n    - mkdir merged\n    - cp job1.txt merged\/\n    - cp job2.txt merged\/\n    - ls -la merged\n  artifacts:\n    paths:\n      - merged\/\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">32 .<\/h2>\n\n\n\n<p>To copy artifacts from two jobs into a common directory in GitLab CI, you can use <strong><code>artifacts<\/code><\/strong> along with the <strong><code>dependencies<\/code><\/strong> or <strong><code>needs<\/code><\/strong> keyword to make artifacts available to a third job that merges them.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 Goal:<\/h3>\n\n\n\n<p>You have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>job1<\/code> and <code>job2<\/code> that create artifacts<\/li>\n\n\n\n<li><code>merge_job<\/code> that collects them into a shared directory (e.g., <code>merged-artifacts\/<\/code>)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">\u2705 Example <code>.gitlab-ci.yml<\/code><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">stages:\n  - build\n  - merge\n\njob1:\n  stage: build\n  script:\n    - <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Job 1 output\"<\/span> &gt; file1.txt\n  artifacts:\n    paths:\n      - file1.txt\n\njob2:\n  stage: build\n  script:\n    - <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Job 2 output\"<\/span> &gt; file2.txt\n  artifacts:\n    paths:\n      - file2.txt\n\nmerge_job:\n  stage: merge\n  needs: &#91;job1, job2]\n  script:\n    - mkdir -p merged-artifacts\n    - cp job1\/file1.txt merged-artifacts\/\n    - cp job2\/file2.txt merged-artifacts\/\n    - <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Merged artifacts:\"<\/span>\n    - ls -l merged-artifacts\n  dependencies:\n    - job1\n    - job2\n  artifacts:\n    paths:\n      - merged-artifacts\/\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here&#8217;s a curated set of 30 most frequently asked real-world questions about GitLab CI\/CD pipeline automation, with clear and concise answers \u2014 perfect for training sessions or real-world use: \u2705&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-49537","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=49537"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49537\/revisions"}],"predecessor-version":[{"id":49554,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49537\/revisions\/49554"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=49537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=49537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=49537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}