Run pipeline when MR gets merged and know the MR's IID

We’re running merge request pipelines and deploy the build to a directory like e.g. /var/www/docs/MR-${CI_MERGE_REQUEST_IID}. This is working fine so that reviewers can not only look at the code but also see the result on an MR-specific website product.

Now, when the MR gets merged, we’d like to clean-up that directory. So, I see 2 missing pieces so far:

  • how do I trigger a pipeline for merged MRs only?
  • how do I know the internal ID of that MR then?

I would try use environment and leverage the stop job which is executed automatically when MR is merged or closed.

Hmm, the name of the environment would also container the MR IID, so I’d be in the same scenario that I don’t know the ID of what should be stopped and/or deleted.

To achieve the desired clean-up of the directory after the MR gets merged, you can follow these steps:

  1. Trigger a pipeline for merged MRs only: You can use GitLab’s CI/CD feature to set up a pipeline that runs only when an MR is merged. GitLab provides predefined environment variables that you can use in your CI/CD configuration.

To trigger a pipeline for merged MRs only, you can use the only keyword in your .gitlab-ci.yml configuration file. The only keyword allows you to specify conditions under which the pipeline should run. In this case, you want the pipeline to run when the MR is merged into the target branch.
thc gummies

Here’s an example of how you can set up the pipeline trigger for merged MRs:

# .gitlab-ci.yml

stages:
  - cleanup

cleanup_build:
  stage: cleanup
  only:
    - merged
  script:
    - echo "Perform clean-up here, e.g., remove the directory /var/www/docs/MR-${CI_MERGE_REQUEST_IID}"

In this example, the cleanup_build job will run only when the MR is merged (only: - merged). You can place your clean-up commands inside the script section of the job.

  1. Get the internal ID (IID) of the merged MR: The CI_MERGE_REQUEST_IID variable you mentioned is an environment variable automatically provided by GitLab CI/CD. It contains the internal ID (IID) of the MR, which can be used to identify the specific MR that triggered the pipeline.

Since the pipeline is already running for merged MRs only, you can safely use the CI_MERGE_REQUEST_IID variable within your script section to reference the MR’s internal ID:

# .gitlab-ci.yml

stages:
  - cleanup

cleanup_build:
  stage: cleanup
  only:
    - merged
  script:
    - echo "Cleaning up MR-${CI_MERGE_REQUEST_IID} directory"
    - rm -rf "/var/www/docs/MR-${CI_MERGE_REQUEST_IID}"

In this example, the script will clean up the directory /var/www/docs/MR-${CI_MERGE_REQUEST_IID} using the MR’s internal ID obtained from the CI_MERGE_REQUEST_IID environment variable.

With these changes, the pipeline will be triggered for merged MRs only, and the clean-up job will remove the corresponding directory based on the MR’s internal ID.

1 Like

Thanks @saith2562 this sounds perfect. However, the only:merged keyword is not documented in `.gitlab-ci.yml` keyword reference | GitLab where I was looking for this. Am I missing something in documentation then?

I don’t think this is really possible / supported yet.

But what you actually need I believe is Review Apps - perhaps it’s worth a shot for your use case.

1 Like

@paula.kokic environments and review apps look nice. Looks like the environment cleanup is a task that needs to be executed manually, but that’s better than nothing.

The cleanup job is triggered manully/when MR is closed/when MR is merged/when review app timeout expires (defined in CI schema).

I would recommend that you leverage Gitlab’s pages. You can look at an example of my setup here. It’s a self hosted instance, but the same applies to gitlab.com.

While I don’t use environment-s in this setup, I would recomend that you use it as it adds the button with the preview link in the MR (very useful) (btw, you can have multiple preview apps per MR, so in case you have multiuple languages built, or whatever… you can have that too).

:warning: You’d be actually viewing the website preview as job artifacts (images, .html files, etc… are served via gitlab pages in the backend). This is used for MR previews (job build in the following example) which (unlike the pages setup; job pages) does not serve default index.htmlif you try accessing a "folder". So make sure that links point to (for example)/docs/some-feature/index.htmlinstead of/docs/some-feature` in the preview builds.

example for gitlab pages previews:

.base:
  image: node:18
  stage: build
  needs: []
  cache:
    key:
      files:
      - yarn.lock
    paths:
    - node_modules
    - .cache
  before_script:
  - yarn install --frozen-lockfile --cache-folder .yarn-cache
  artifacts:
    expire_in: 1 month
    paths:
    - public

build:
  extends: .base
  parallel:
    matrix:
    - ELEVENTY_LOCALE:
      - it
      - en
      - sl
  environment:
    name: review/$CI_COMMIT_REF_SLUG-$ELEVENTY_LOCALE
    action: start
    deployment_tier: development
    url: https://${CI_PROJECT_ROOT_NAMESPACE}.${CI_PAGES_DOMAIN}/-/${CI_PROJECT_PATH#${CI_PROJECT_ROOT_NAMESPACE}/}/-/jobs/$CI_JOB_ID/artifacts/public/index.html
  variables:
    GIT_DEPTH: 0
    ELEVENTY_PATHPREFIX: /-/${CI_PROJECT_PATH#${CI_PROJECT_ROOT_NAMESPACE}/}/-/jobs/$CI_JOB_ID/artifacts/public/
    ELEVENTY_ADD_INDEXHTML_SUFFIX: "true"
    DEBUG: Eleventy*
  script:
  - yarn run build
  - echo "View the generated files on ${CI_ENVIRONMENT_URL}"
  rules:
  - if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH

pages:
  extends: .base
  variables:
    LINKTO_EN: "https://my-page.eu"
    LINKTO_IT: "https://my-page.it"
    LINKTO_SL: "https://my-page.si"
  script:
  - ELEVENTY_LOCALE=en ELEVENTY_OUTPUT=pages/en yarn run build
  - ELEVENTY_LOCALE=sl ELEVENTY_OUTPUT=pages/sl yarn run build
  - ELEVENTY_LOCALE=it ELEVENTY_OUTPUT=pages/it yarn run build
  rules:
  - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH

GitLab pages is a nice idea for this, thanks for the suggestion. Will give that a try too, for now the review app approach is working nicely already.

Well yeah, it’s the same approach. The only difference is that with gitlab pages you remove the “pet” from your setup (that being the webserver where the preview files are deployed). Currenty, if I understand it correctly, you’re hosting the previews on a standalone webserver. which has to be maintained separately from gitlab.

That’s correct, but that server is already available for the published version of that site. And we have a deployment pipeline which dynamically issues SSL certs and everything else, something we also require for staged web sites that we build for clients.