Azure Pipelines for Publishing to GitHub Pages

Please note: This article is only available in English.
Using the free Azure DevOps build jobs for publishing a React SPA on GitHub pages.

In the recent months I was (among other things) quite busy with getting into GraphQL and extending it to work well in a SOA consisting of dozens of micro services. The result of this is called GQLX (short for GraphQL eXtended) and I was fortunate enough to get the permission for making this work available as OSS.

While we have not officially published / advertised the technology yet, we are already using it internally. All our services use the npm published reference implementation for consistency checks, our gateway is fully relying on it for generating the schema and interpreting it, and our developers are using the web app for getting information quickly. Right now this web app is hosted on GitHub pages and needs to be deployed manually, i.e., from a dev's machine using the comamnd line npm run deploy.

One of the things we wanted to have is to have the publish process (i.e., build and deploy) of this React Single-Page Application (SPA) automated. Naturally, we could have went for Travis CI (that is being used on some other projects), but instead we tried the Azure Pipelines integration in GitHub.

While the start (i.e., integrating the basic pipeline) is ultra simple (I would even consider calling it trivial) custom tasks seem to be a little bit more problematic. In my case I faced an issue with just calling the gh-pages command that will essentially just do a git push.

The solution to overcome all problems incl. "invalid device or username" to access GitHub for pushing, "who are you" for using Git, or "the password is displayed in the logs" is realized in 3 simple steps.

Step 1

Open the Azure Pipeline in the Azure DevOps page. Go to variables and create a new variable (e.g., called github_pat). Make sure to check the secret check box. The value of this environment variable is extracted in the second step.

Step 2

Go to your GitHub settings and enter the developer settings tab. In there we have the personal access tokens (PATs). These are quite heavy security keys that will have direct access to your account. Treat them very carefully. However, they offer certain benefits:

  • They can be revoked
  • They can be targetted (at different APIs) / equipped with different claims
  • They can be prolonged / extended
  • They can expire

We should create a new token that is only capable of accessing a certain repository (pull, push, ...). This new PAT should be immediately copied over to the value field from step 1.

gh_github_pat

Step 3

Now we need to adjust the azure-pipelines.yml file. Let's assume we started with a basic Node.js build process (since we have a React SPA). We need to transform it from the basic version to this:

pool:
  vmImage: 'Ubuntu 16.04'

trigger:
- source

steps:
- checkout: self
  persistCredentials: true
- task: NodeTool@0
  inputs:
    versionSpec: '8.x'
  displayName: 'Install Node.js'
- script: |
    git config user.email "yourmail" 
    git config user.name "yourname"
    npm install
    npm run deploy -- -r https://$(github_pat)@github.com/yourrepo.git
  displayName: 'npm install and build'

What does it do? Well, most importantly we use an explicit URL for our repository located at GitHub. This URL contains the access information in form of the PAT. The PAT is received from the environment variable and won't be shown in any logs.

In order to use Git in the deploy script (which is only using gh-pages underneath, hence the -r flag) we need to set up git locally. The relevant lines are the ones that call git config. Make sure to enter your details there.

Finally make sure to get the right URL for your repository. After that try it out, grab the status badge and place it in your README to view the current status of the build to interested people.

gh_badge

And that's it! With these small changes we added a full CI/CD pipeline for our simple GQLX web app. No more local deployments!

Created . Last updated .

References

Sharing is caring!