Working with NX, Railway and CI/CD

Avatar of Faraz PatankarFaraz Patankar
·

Railway has first-party support for NX monorepos through Nixpacks, users may instead want to opt for GitHub Actions in order to only create deployments for the affected services whenever they push a change.

In this article we will walk you through deploying a sample project on Railway to achieve that exact workflow.

Setting up our sample project

We will use the npm-libs repository by community member: IgnisDa as our sample project. Within this repository, we will deploy the remix-pagination-demo project.

You can start by forking that repository and deploying it within a project on Railway. Once you add the repository, go to the variables section and set the NIXPACKS_NX_APP_NAME variable to remix-pagination-demo.

Configuring the NX app name

Configuring the NX app name

Next, we can head over to the service settings and disable the GitHub trigger as we will be using GitHub actions to automatically trigger deployments for our project.

Disabling the GitHub trigger on Railway

Disabling the GitHub trigger on Railway

Next, create two separate environments. One for our main branch and one for the dev branch and head over to the project settings to create a project token for each environment.

Creating project tokens

Creating project tokens

Setting up our GitHub repository

Copy the project tokens from Railway and add them as repository secrets on GitHub. They should have the following naming scheme:

RAILWAY_TOKEN__<project_name>_<railway_environment>
Repository secrets on GitHub

Repository secrets on GitHub

The GitHub action

Now, we need to set-up the workflow within GitHub to trigger a new deploy.

The GitHub action workflow will:

  • Run on every commit to the main and dev branches
  • Test if a particular project has been affected
  • If it has, deploy it to the correct environment on Railway
name: Deploy affected projects

on:
  push:
    branches:
      - main
      - dev

env:
  NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - uses: ./.github/actions/setup
        name: Setup environment

      - name: Set base commit hash
        run: |
          #!/usr/bin/env bash
          commit=${{ github.event.before }}
          if git branch --contains "$commit"; then
            echo "No force push detected, continuing..."
          else
            # get the commit before this one
            commit=$(git log --format="%H" -n 2 | tail -n 1)
          fi
          echo "BASE_COMMIT=$commit" >> $GITHUB_ENV

      - name: Display base commit
        run: echo "$BASE_COMMIT"

      - name: Lint affected
        run: pnpm nx affected --target=lint --parallel=6 --base=$BASE_COMMIT --head=HEAD

      - name: Build affected
        run: pnpm nx affected --target=build --parallel=6 --base=$BASE_COMMIT --head=HEAD

      - name: Dump access secrets into file
        run: |
          mkdir -p ./dist
          echo '${{ toJSON(secrets) }}' >> ./dist/secrets.json

      - name: Deploy affected
        run: ./deployment/railway-trigger.sh

The main steps to note here are the:

  • Dump access secrets to file step which converts the secrets into json format and dumps them into a file. This can be a potentially exploitable step if used in public repositories, so please make sure you take the appropriate cautions.
  • Deploy affected step which triggers the railway-trigger.sh script shared below.

Conclusion

With that, we have set up CI/CD to deploy an NX monorepo to Railway using GitHub actions. You should be able to use this as a reference to deploy your own NX monorepos. If you run into any issues, feel free to reach out to us on our Discord.

This post is a community post thanks to IgnisDa’s. This is based off of a post on their own blog. Click here to read the original post!