How to Continuously Deploy a Front-end Project Using GitLab and Surge
I recently built a web project from scratch for a client who had no existing infrastructure for web development. As a believer in continuous integration I decided to go with automated deployment from the very beginning.
After a quick research on off the shelf solutions and came up with the following combination:
- Host the source code on GitLab
- Build and deploy using GitLab’s continuous integration pipelines
- Host the web application on Surge
The advantage of this setup is the lack of the need for setting up your own server software while both cloud solutions have free plans to start your project with. Moreover GitLab’s free plan includes private repositories.
This blog post will guide you through the first steps of setting up GitLab and Surge for your own web project.
Requirements
It is assumed you know the basics of Git, have a GitLab account set up and configured with your ssh key and have the following software installed:
Setting up the project
If you don’t have one yet, use your favorite text editor or IDE to create a web
project in an empty folder with an index.html
at the top level. You can also
copy the html, js and css files from the example project I
created for this post.
Publishing the project to GitLab
First you will need a local Git repository. Set one up using the commands below:
git init
git add index.html main.css main.html
git commit -m 'First commit'
Next create a new project on GitLab and publish the local repository with these commands (copy the origin URL from GitLab):
git remote add origin git@gitlab.com:some-username/my-project.git
git push -u origin --all
Adding static web hosting
We will use Surge for quick and free static web hosting. It comes with a command line tool that can be installed using npm. Run these commands in the root of the project:
npm init -y # If you don't have a package.json yet
npm install --save-dev surge
node_modules/.bin/surge .
The first time it’s used Surge prompts for an email and password. Choose a subdomain you like or let Surge generate a random one. The output should look like this:
$ node_modules/.bin/surge .
Surge - surge.sh
email: example@example.com
token: *****************
project path: .
size: 1 files, 57 bytes
domain: my-awesome-project.surge.sh
upload: [====================] 100%, eta: 0.0s
propagate on CDN: [====================] 100%
plan: Free
users: example@example.com
IP Address: 45.55.110.124
Success! Project is published and running at my-awesome-project.surge.sh
Open http://my-awesome-project.surge.sh in your browser to see the published web project.
Important: Surge prompts for a subdomain every time you run it, if you want to stick with one, save it with the project:
echo my-awesome-project.surge.sh > CNAME
This is the right moment to make a Git commit:
echo node_modules >> .gitignore # Avoid commiting Node.js dependencies
git add CNAME package.json package-lock.json .gitignore
git commit -m 'Added Surge static hosting'
Setting up continuous deployment
GitLab’s continuous integration pipeline can be configured with
.gitlab-ci.yml
placed in the root folder of the project. Create one with the
following content:
image: node
before_script:
- npm install
deploy:
stage: deploy
script:
- node_modules/.bin/surge .
Before pushing .gitlab-ci.yml
to GitLab the pipeline has to be configured
with Surge access credentials so that it can publish to the domain you
configured in the previous step. First obtain a token from Surge:
$ node_modules/.bin/surge token
Surge - surge.sh
email: me@example.com
token: *****************
token: <COPY THE TOKEN FROM HERE>
Next go to GitLab -> Your project -> Settings -> CI / CD -> Secret variables
- Add a key named
SURGE_LOGIN
and set the value to the email you use with Surge - Add a key named
SURGE_TOKEN
and paste the token into the value from the output ofsurge token
And now commit and push .gitlab-ci.yml
to GitLab. In a short while you should
see the pipeline running under GitLab -> Your project -> CI / CD -> Pipelines.
If it fails click on the red failed pipeline and the failed job to see the full
terminal output of the deploy job for troubleshooting.
From now on every change you push to GitLab will automatically be deployed to Surge.
Bundling the project
No serious front-end project can get away without a bundling tool nowadays. To keep things simple I used AssetGraph-builder. This tool has the advantage of taking care of bundling JavaScript, CSS and HTML files by using an HTML file as an entry point with zero configuration - perfect for a newly created simple web application.
Setting up AssetGraph-builder is not more complicated than running these two commands:
npm install --save-dev assetgraph-builder
node_modules/.bin/buildProduction --outroot=dist index.html
Check the contents of dist
folder to see the bundled project.
To do the bundling automatically on GitLab, tweak the contents of
.gitlab-ci.yml
:
image: node
before_script:
- npm install
deploy:
stage: deploy
script:
- node_modules/.bin/buildProduction --outroot=dist index.html
- cp CNAME dist/
- node_modules/.bin/surge dist
Commit and push all changes to GitLab to run the pipeline. Don’t forget to add
dist
folder to .gitignore
. After a short while the bundled project should
be republished to Surge.
Next steps
It should be easy to adopt this approach to your favorite front-end toolchain. Using Yarn instead of npm or bundling with Webpack or Browserify is not much different from the tools used here.
A decent software project has automated tests. Fortunately we already have a pipeline set up with the potential of running our tests. Read the GitLab CI documentation on how to set up advanced pipelines with multiple jobs and stages.
The examples above are published to a GitLab project including public access to the pipeline.
Alternatives
If your project is actually a static web site without the need for a sophisticated bundling process or automated tests a static site generator and/or GitLab Pages or GitHub Pages would do the job.
There are also alternatives for continuous integration, Travis CI for example is free for public projects.