CI/CD

I learn best by doing. I had heard continuous integration and continuous deployment thrown around for a while, often as buzz words. My current employer doesn’t really do either of these though we do use Jenkins as a deployment server. I’ve never seen it in action but from what I understand it has hooks into some of our java container hosts like WebLogic. It copies files over and understands compilation errors. Again I’ve never actually used it so this is just my understanding from what I’ve heard at work. GitLab gives you 2000 CI minutes which I never used. With my learning of Go it and pushing my code into it I started getting template suggestions for testing. The template provided needed a few edits and it started compiling my code and testing it for errors. It would place the built binary in a kind of hidden directory. It would do this on every push and took about 5 minutes. It used environment variables to protect credentials being in the config file.

Deployment was more difficult. I had trouble finding a good example out there on how to deploy my web app written in Go. Finally I found an alright example with a shell script that copied files. I augmented it with a service created on my web server.

Here’s my gitlab-ci.yml:

# This file is a template, and might need editing before it works on your project.
image: golang:latest

variables:
  # Please edit to your GitLab project
  REPO_NAME: gitlab.com/murphyslaw4267/cool_go_app
  APP_NAME: cool_go_app
  S3_BUCKET_NAME: "serverhobbyistohio"
  AWS_ACCESS_KEY_ID: $AWSID
  AWS_SECRET_ACCESS_KEY: $AWSSecret

# The problem is that to be able to use go get, one needs to put
# the repository in the $GOPATH. So for example if your gitlab domain
# is gitlab.com, and that your repository is namespace/project, and
# the default GOPATH being /go, then you'd need to have your
# repository in /go/src/gitlab.com/namespace/project
# Thus, making a symbolic link corrects this.
before_script:
  - mkdir -p $GOPATH/src/$(dirname $REPO_NAME)
  - ln -svf $CI_PROJECT_DIR $GOPATH/src/$REPO_NAME
  - cd $GOPATH/src/$REPO_NAME

stages:
  - test
  - build
  - deploy

format:
  stage: test
  script:
    - go get github.com/aws/aws-sdk-go
    - go fmt $(go list ./... | grep -v /vendor/)
    - go vet $(go list ./... | grep -v /vendor/)
    - go test -race $(go list ./... | grep -v /vendor/)

compile:
  stage: build
  script:
    - go get github.com/aws/aws-sdk-go
    - echo $CI_PROJECT_DIR
    - go build -race -ldflags "-extldflags '-static'" -o $CI_PROJECT_DIR/build/$APP_NAME
  artifacts:
    paths:
      - build/
  
deploy:
  stage: deploy
  only:
  - master
  image: ubuntu
  before_script:
  - apt update -y
  - apt install rsync -y
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh
  - ssh-keyscan webapp1.serverhobbyist.com >> ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts
  - rsync -ae ssh ./build/* root@webapp1.serverhobbyist.com:/var/www/go/cool_go_app/
  - rsync -ae ssh ./*.html root@webapp1.serverhobbyist.com:/var/www/go/cool_go_app/
  script:
  - bash .gitlab-deploy.sh


Leave a Reply

Your email address will not be published. Required fields are marked *