I have a vanilla JavaScript application that I host on GitLab Pages. Recently, I have been making changes and bug fixes that have been breaking the site, and I haven't noticed until already having pushed the changes.
In an effort to reduce user exposure to bugs, I would like to publish two sites in separate folders:
public/
: master
branch; the official websitepublic/staging/
: staging
branch; the nightly buildI would like for these to correspond to two different branches: master
and staging
Reading GitLab CI for GitLab Pages, it sounds like this is not even possible. I'm hoping I'm reading this wrong.
default:
image: node:latest
test:
stage: test
script:
- npm install
- node test.js
only:
- staging
- master
staging:
stage: deploy
environment: staging
script:
- mkdir -p public/staging
- cp -r www public/staging
artifacts:
paths:
- public
only:
- staging
pages:
stage: deploy
environment: production
script:
- mkdir -p public
- cp -r www public
artifacts:
paths:
- public
only:
- master
Is this possible? Is it possible to deploy two different folders from two different branches?
Interestingly, it is possible to post from any branch, just not from any job.
To do this, I needed to make two changes:
GitLab has the ability to cache folders. Generally this is used to speed up builds by caching downloaded drivers. There is no reasons I could not use this to store the public
folder. This way when I make changes to staging
, I will remember the state of the root
application:
cache:
paths:
- public
The next trick would be to publish pages to the appropriate folder, depending on current branch being built. To do this, we can look to GitLab CI/CD Environment Variables; in particular:
CI_COMMIT_REF_SLUG
: The current branchCI_DEFAULT_BRANCH
: the default branch (master)Knowing these two values, we can do a bit of bash
to determine the correct place to write the content to.
pages:
stage: deploy
script:
- dir="$CI_COMMIT_REF_SLUG"
- if [ "$CI_COMMIT_REF_SLUG" == "$CI_DEFAULT_BRANCH" ]; then dir=""; fi;
- dir="public/$dir"
- echo "Deploying to $dir"
- mkdir -p $dir
- cp -r www $dir
artifacts:
paths:
- public
only:
- staging
- master
Don't forget to limit pages to only staging
and master
.
WARNING
I'm not satisfied with this.
I think it would be better to maintain the cache somewhere completely different and copy them in at a later stage, but completely re-writing the public folder each time.
The current solution will build cruft over time, but the basic idea is sound.