Skip to content

Instantly share code, notes, and snippets.

@mjaliz
Last active September 17, 2023 13:11
Show Gist options
  • Save mjaliz/289be0d26a2f7c6eea80c2988ccadfca to your computer and use it in GitHub Desktop.
Save mjaliz/289be0d26a2f7c6eea80c2988ccadfca to your computer and use it in GitHub Desktop.
Notes about GitlabCI/CD

This gist is some notes about Gitlab CI/CD

To start a pipline you need to create a specfic file: .gitlab-ci.yml

We need jobs to do anything in gitlab CI:

build the car:
    script:
      - mkdir build
      - cd build
      - touch car.txt
      - echo "chassis" > car.txt
      - echo "engine" > car.txt
      - echo "wheels" > car.txt
     

Then commit the changes and pipline would be start.

Add another job to test the prev job:

 build the car:
    script:
      - mkdir build
      - cd build
      - touch car.txt
      - echo "chassis" > car.txt
      - echo "engine" > car.txt
      - echo "wheels" > car.txt
      
 test the car:
    script:
      - test -f build/car.txt
      - cd build
      - grep "chassis" car.txt
      - grep "engine" car.txt
      - grep "wheels" car.txt

Gitlab by default runs the jobs in parallel to in order to specify the order of jobs we need to define stages, note that the order of stages matter to run each stage.

 stages:
    - build
    - test
    
 build the car:
    stage: build
    script:
      - mkdir build
      - cd build
      - touch car.txt
      - echo "chassis" > car.txt
      - echo "engine" > car.txt
      - echo "wheels" > car.txt
      
 test the car:
    stage: test
    script:
      - test -f build/car.txt
      - cd build
      - grep "chassis" car.txt
      - grep "engine" car.txt
      - grep "wheels" car.txt

Note: It's not necessary to stage name and jobs have the same name, we can have different name for jobs and stages.

Separate jobs do not exchange any data if not told to exchange any data, to tell a job save and share some thing we need artifact:

 stages:
    - build
    - test
    
 build the car:
    stage: build
    script:
      - mkdir build
      - cd build
      - touch car.txt
      - echo "chassis" > car.txt
      - echo "engine" > car.txt
      - echo "wheels" > car.txt
    artifacts:
      paths:
        - build/ # save all the build folder
      
 test the car:
    stage: test
    script:
      - test -f build/car.txt
      - cd build
      - grep "chassis" car.txt
      - grep "engine" car.txt
      - grep "wheels" car.txt

This pipline woudl be fail again, because instead of appending text to car.txt we are replacing the entire content, to fix this we have:

stages:
   - build
   - test
   
build the car:
   stage: build
   script:
     - mkdir build
     - cd build
     - touch car.txt
     - echo "chassis" >> car.txt
     - echo "engine" >> car.txt
     - echo "wheels" >> car.txt
   artifacts:
     paths:
       - build/ # save all the build folder
     
test the car:
   stage: test
   script:
     - test -f build/car.txt
     - cd build
     - grep "chassis" car.txt
     - grep "engine" car.txt
     - grep "wheels" car.txt

Gitlab runner by default uses ruby:2.5 for docker image, we can change the image like this:

build website:
   image: node:lts
   script:
     - npm install
     .
     .
     .

A gitlab job will fail if the returned status code is not zero.

If we define a test stage like below the test stage will also use the same docker image as build in our case node, we can change the image for test stage and use a smaller image like alpine.

stages:
- build
- test

build website:
  image: node:lts
  script:
    - npm install
    .
    .
    .
test artifacts:
  image: alpine
  stage: test
  script:
    - grep -q "Gatsby" ./public/index.html

We can run jobs in parallel if we assign multiple jobs to a stage:

stages:
- build
- test

build website:
 image: node:lts
 script:
   - npm install
   .
   .
   .
test artifacts:
 image: alpine
 stage: test
 script:
   - grep -q "Gatsby" ./public/index.html

test website:
 image: node:lts
 stage: test
 script:
   - npm install
   - npm install -g gatsby
   - gatsby serve
   - curl http://localhost:9000 | grep -q "Gatsby"

If we want to run a job or script in background we can use & at the end of our script:

stages:
- build
- test

build website:
  image: node:lts
  script:
    - npm install
    .
    .
    .
test artifacts:
  image: alpine
  stage: test
  script:
    - grep -q "Gatsby" ./public/index.html

test website:
  image: node:lts
  stage: test
  script:
    - npm install
    - npm install -g gatsby
    - gatsby serve &
    - sleep 3 # note this sleep is not a good solution
    - curl http://localhost:9000 | tac | tac | grep -q "Gatsby"

We can define secretes and variables in settings > CI/CD > variables

Note: we can define the default docker image out of all jobs and also define specific image for each job:

image: node:lts

stages:
- build
- test

build website:
 script:
   - npm install
   .
   .
   .
test artifacts:
 image: alpine
 stage: test
 script:
   - grep -q "Gatsby" ./public/index.html

test website:
 stage: test
 script:
   - npm install
   - npm install -g gatsby
   - gatsby serve &
   - sleep 3 # note this sleep is not a good solution
   - curl http://localhost:9000 | tac | tac | grep -q "Gatsby"

We can use predefined envoirenment variables in gitlab for so many cases. one of them is to include the commit hash to find that which commit resulted the deployed app. for this goal we can use CI_COMMIT_SHORT_SHA. we can assume a marker for this id in our code and replace it during the build using sed command.

sed -i "s/old_word/new_word/g" inputfile

-i for edit in place(edit the same file, don't create new one)
s for subtitute
g for global replacement

sed -i "s/%%MARKER%%/$CI_COMMIT_SHORT_SHA/ ./public/index.html

note: make sure to use double quotes otherwise the variable will note be replaced
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment