CI using Gitlab and Heroku - node.js

I'm using react-starter-kit for developing my web application, and Gitlab as my remote git repository.
I want to configure a continuous deployment such that on every push to the master, the npm run deploy script will be executed.
From my local pc, executing npm run deploy builds the node application and push it to the remote heroku git repository. It uses the local credentials on my pc.
I have configured the gitlab runner (in the .yml file) to execute the same npm run deploy, but it fails with Error: fatal: could not read Username for 'https://git.heroku.com': No such device or address.
I need to find a way to authenticate the gitlab runner to heroku. I have tried to set env variable HEROKU_API_KEY, but it also didn't work.
How can I push from my gitlab runner to my heroku git repo?

You should use dlp in your yml. Try something like this in the .gitlab-ci.yml:
before_script:
- apt-get -qq update
- npm set progress=false
- npm install --silent
deploy:
script:
- npm run deploy
- apt-get install -yqq ruby ruby-dev --silent
- gem install dpl
- dpl --provider=heroku --app=your-app-name --api-key=$HEROKU_API_KEY
only:
- master
You preferaby want to add the env variable $HEROKU_API_KEY from GitLab, not here directly.

Related

How to integrate various services for building a project in GitLab CI/CD?

I have a project that requires npm and gradle for build, and docker for building and pushing the image.
At first I thought that I should create my own ubuntu image with gradle and npm setup, but I found out that is not what docker images are for.
So I hoped to run official Gradle and node images as a service so that my script can call those commands, but that is not happening for some reason.
My .gitlab-ci.yml:
variables:
IMAGE_NAME: my.registry.production/project
IMAGE_TAG: $CI_COMMIT_BRANCH
GIT_SUBMODULE_STRATEGY: recursive
stages:
- build
- deploy
build_project:
stage: build
image: ubuntu:jammy
services:
- name: node:12.20
alias: npm
- name: gradle:6.3.0-jre8
alias: gradle
before_script:
- git submodule init && git submodule update --remote --recursive
script:
- cd project-server && npm install && gradle clean build -Pprod -Pwar -x test -x integrationTest
deploy_image:
stage: deploy
image: docker:20.10.17
services:
- name: docker:20.10.17-dind
alias: docker
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
script:
- docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD my.registry.production
- docker build -t $IMAGE_NAME:$IMAGE_TAG .
- docker push $IMAGE_NAME:$IMAGE_TAG
If anyone has any info on how to solve this I would greatly appreciate it, since I’m a novice DevOps.
Edit 1:
My Dockerfile for custom image with Gradle and Node installed.
FROM ubuntu:jammy
LABEL key=DevOps
SHELL ["/bin/bash", "--login", "-i", "-c"]
RUN apt update && apt upgrade -y && apt install curl -y
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
RUN source /root/.bashrc && nvm install 12.14.1
RUN nvm install 12.20.0
RUN apt install zip unzip
RUN curl -s "https://get.sdkman.io" | bash
RUN source "$HOME/.sdkman/bin/sdkman-init.sh"
RUN sdk install java 8.0.302-open
RUN sdk install gradle 3.4.1
SHELL ["/bin/bash", "--login", "-c"]
CMD [ "bin/bash" ]
After I run it, it says that npm is not found in $PATH, I tried Java, Gradle as well but they weren't found in the path as well.
I don't know why since I installed them as you can tell from the Dockerfile.
As I know, a docker image is equal to one build. So if you have multiple services you need to build each one into docker image then you can encapsulate all images into docker-compose.yml file.
I think you can do the following:
Build the npm project into a docker image
Build the Gradle project into a docker image
Write the docker-compose.yml file and put both images.
Once you have done it, the pipeline calls the docker-compose.yml file.
I hope this will be helpful.
Consider a few suggestions based on the fundamental concepts about the deployment in your CI/CD pipeline:
Remove the services keyword. Reference GitLab's official documents on what the services keyword inside gitlab-ci.yaml file is not for. The feature is used
to provide network accessable services to your job runtime (like
a database): https://docs.gitlab.com/ee/ci/services/index.html
Your project uses npm as a dependency management system, Gradle is
a build tool. Both of these pieces of software are more than
appropriate to run on the host operating system of the container
runtime inside GitLab's Pipeline job. You need these tools to assemble some build artifact as a result of the job on the same host your code has been downloaded on in the Runner.
Think about the overall size of the base image in your build_project job and consider how time to download the image over the network on to the Runner will impact your job and overall pipeline duration. If performance can be improved by baking build dependencies into a custom Dockerfile do this. If your image is too large, instead use shell commands inside the script keyword block to download them at the runtime of the job. There can be pros and cons for both.
Break shell scripts to one command per line for easier troubleshooting of failures in your scripts. You will be able to see the line number of the command which returned a non-zero exit code in your job logs:
...
script:
- cd project-server
- npm install
- gradle clean build -Pprod -Pwar -x test -x integrationTest
...
It's recommended to use the Gradle wrapper (gradlew) most of the time instead of the gradle executable directly. Configure this within your project and check the configuration files for the wrapper into your version control system and this will simplify your build dependency: https://docs.gradle.org/current/userguide/gradle_wrapper.html

Github Actions and npm - npm: command not found

I've created a action for a deployment on github actions. This all works with composer install and git pulling the master branch. However on my digital ocean droplet, I get the issue
bash: line 4: npm: command not found
If i ssh into my server i can use npm perfectly fine. This was installed via nvm and uses the latest version but for some reason its not accessable via the action.
My deployment script is
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy Laravel APP
uses: appleboy/ssh-action#v0.1.4
with:
host: ${{secrets.SSH_HOST}}
key: ${{secrets.SSH_KEY}}
username: ${{ secrets.SSH_USER }}
script: |
cd /var/www/admin
git pull origin master
composer install
npm install
npm run prod
I presume this is more to do with the setup from nvm as i can use this via ssh but as they use the same user to log in via ssh, i can't seem to see an issue.
Any ideas how I can resolve this issue to give access/allow github actions to use npm?
I didn't find a solution for the nvm issue, installing npm via a different way resoleved this issue.
I had the same issue, and finally found the solution.
I could solve the issue by adding the following lines before running npm commands.
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
These commands helps the terminal fix the node path installed by nvm.
Reference link is here.

Gitlab CI - npm' is not recognized as an internal or external command, operable program or batch file

I am trying to run a CI in gitlab
image: node:latest
stages:
- deploy
production:
stage: deploy
before_script:
- npm config set prefix /usr/local
- npm install -g serverless
script:
- serverless deploy
I am using the docker image like they suggest but it cannot find npm (or node)
How can I get this working?
Well, this is a bit weird, as your ci is correct.
If you are just using gitlab.com and their shared runners then this .gitlab-ci.yml will work.
One possible reason could be you have runners added as ssh/shell executors in the project repo. If so then the image tag you specified will be simply ignored.
So error like command not found could occur because of the server where you have added the runner doesn't have nodejs installed, and this error will occur for the npm config... command in before script with exit code 127 and pipeline will fail just there and stop.
If you have multiple runners then tag them and tag your jobs in ci.yml as well.
And if you are trying to run the job on your own server then you got to install docker first.
BTW for docker image node:latest you don't need npm config set prefix /usr/local as it already is /usr/local

Copy build folder to my repository

I have this bitbucket-pipelines.yml, is there any way to copy the build that is created by npm run buid into my repository?
image: node:6.9.4
pipelines:
branches:
master:
- step:
caches:
- node
script:
- npm install
- npm run build
If you mean saving the build as a Download in your Bitbucket repository, then we have a guide on how to do it via the Bitbucket API. The basic steps are:
Create an app password for the repository owner
Create a Pipelines environment variable with the authentication token
Upload your artifacts to Bitbucket Downloads using curl and the Bitbucket REST API
The details of how to do this are covered in the guide.
If you mean committing the build back to the Git repository, we wouldn't recommend that. Storing build output in Git isn't ideal - you should use BB downloads or an npm registry for that. But if you really want to, you can do it by following the guide above to create an app password, then pass it as an environment variable into Pipelines, set it in a HTTPS git remote, then use git push to upload it back to Bitbucket.

Build and deploy node app to Openshift using Gitlab CI

Just mount a Gitlab in digitalocean to keep track of versions of some projects, but now I've read a little about Gitlab I wonder if you can set Gitlab CI so that each time you do a commit automatically make a build of application and if the build is successful can do a deploy to OpenShift.
I think my .gitlab-ci.yml should look something like this:
stages:
- build
- deploy
before_script:
- npm install
job_build:
stage: build
script:
- grunt build
job_deploy:
stage: deploy
But I really do not know if this is as valid and neither tell Gitlab CI must only make a git push to OpenShift repository.
After much reading and searching finally found documentation about this [1], in the end I have resolved some file using the following .gitlab-ci.yml
stages:
- build
- deploy
job_build:
stage: build
script:
- npm install -g grunt-cli
- npm rebuild node-sass
- npm install
- grunt build
job_deploy:
stage: deploy
script:
- apt-get update -yq
- apt-get install -y ruby-dev rubygems
- gem install dpl
- dpl --provider=openshift --user=$OPENSHIFT_USER --password=$OPENSHIFT_PASS --domain=mydomain --app=example
only:
- master
The magic happens with a Travis library call dpl [2] that supports a lot of providers [3]
[1]http://doc.gitlab.com/ce/ci/deployment/README.html
[2]https://github.com/travis-ci/dpl
[3]https://github.com/travis-ci/dpl#supported-providers

Resources