learning to work with Actions

GitHub Actions is a platform that allows you to automate workflows directly in your repository. You can create, customize, run, combine, and share actions to perform any job, including CI/CD. Thus, using the tool you can simplify and customize software development.

Key terms in GitHub Actions are workflow, task, and action. A workflow is a set of actions performed in response to events, such as commits or requests to merge branches. Each task in a workflow runs on a virtual machine and can involve multiple steps. Actions are custom steps that can be reused across different workflows, making it easy to create and maintain automated tasks.

Preparing the server

First of all, let's prepare

cloud server

which will host our demo project. To do this, we will take the following steps.

In the control panel, create an account or log in if you already have an account. Inside we select Cloud platform → Servers and press Create a server.

In the settings, specify an arbitrary name and set the minimum configuration. The application does not require a lot of power to run.

Select all the necessary parameters and click

Create a server

.

We return to the control panel and go to the console of the created server. To log in you need a login (root) and password. Click LMB on the icon Hotkeys and add the generated password.

That's all for now with setting up the server. We'll return to it when we automate the deployment of the frontend and backend.

1. Automation of code review (eslint/tests)


Let's start by setting up GitHub Actions to run automatically eslint and tests with each command push or pull request.

Setting up the file structure

The first step you need to take to get started with actions is to create a special directory

workflows

where we will store configuration files for GitHub Actions.

Go to the project directory and prepare the necessary paths:

cd /path/to/your/project
mkdir -p .github/workflows

Elementary action

Now we can create our first configuration file. Let's create a simple action. So we will first get acquainted with the capabilities of GitHub Actions, and only then we will move on to writing full-fledged logic.

Let's start with the file TEST.yml:

name: TEST
on: [push]
jobs:
  our-first-job:
    runs-on: ubuntu-latest
    steps:
      - name: Run console log
           run: echo "Hello GitHub Actions!" 

On the first line using the key

name

we set a name for the action. Next in the key value

on

we describe the events upon the occurrence of which it should occur. Record

on: [push]

says that the reaction will be to all push commands in the repository – regardless of the branch to which the changes came. We'll also discuss how to make the adjustment more precise.

Keyword jobs describes the “tasks” that GitHub must perform: one or more. In our example our-first-job – arbitrary name.

And now we come to the instructions themselves. Here we describe the steps that make up the task and the operating system required to carry them out.

Full action

Let's move on to creating an action, where we will describe the checks that must be performed before merging the code with any branch. Let's name the file

CI.yml

:

name: CI
on: [pull_request]
jobs:
  check-lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.12.2'
      - name: Install dependencies
        run: npm ci
      - name: Run linter
        run: npm run lint
  check-tests:
          runs-on: ubuntu-latest
          steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.12.2'
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test

The configuration file above will run the linter and tests every time you open

pull request

.

Here the instructions are more complicated, because plugins are used:

If we translate the instructions into understandable language, we have literally written down the following steps.

  1. Launch the latest Ubuntu
  2. Do it git clone from our repository.
  3. Install a node.
  4. Install the project dependencies.
  5. Run the command.

Flexible event setup

We can configure our action more flexibly, for example, so that it fires only for certain branches:

on:
  push:
    branches: [main, dev]
  pull_request:
    branches: [main]

The fragment above says that the action will occur when

push

in the branch

main

And

dev

as well as when creating

pull request

V

main

.

2. Automatic frontend deployment


Now let's look at how to set up automatic delivery of a front-end application to the server using GitHub Actions. Let’s use a not-so-usual method—we’ll write a Bash script and place it on the server to connect remotely and run the script as needed through “actions.”

Preparing the server

First of all, we need to prepare our server. To do this, we will download the necessary software (Nginx, NVM, Git) and configure SSH keys for a secure connection.

Install server nginx It's simple – just enter the command:

sudo apt install nginx

To get NVM (Node Version Manager), you need to download and run the installation script:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

Next, we determine the location of the settings directory:

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

Install Git:

sudo apt install git

Let's create SSH keys to work with

git clone

. You will be required to enter a file name and password.

ssh-keygen -t ed25519 -C "Ваш любой комментарий"

The -t option specifies the encryption algorithm. We won’t dwell on his choice in detail; those interested can take a look

to the discussion on StackExchange

which compares the features of various ciphers, including the widely used RSA.

The comment is not required, but is useful when there are a lot of generated pairs.

Two keys should appear: private and public. To make sure of this, let's go to the directory where the SSH keys are stored:

cd /root/.ssh/

In the same directory we will create or add a file

config

to clarify which key is used to connect to GitHub. Let's use the simplest editor

nano

:

nano config

We add an entry that links the host and the keys used. Field replace it with the name of the file containing the private key for connecting to GitHub:

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/<your-private-key>
  StrictHostKeyChecking no

A small digression about SSH keys

It's time to clear up one confusing point. Our instructions interact with two pairs of SSH keys at once:

  • created locally on your computer to connect to the VPS;
  • located on the VPS for authorization in the repository.

The first pair has already been created. Its keys are used when connecting to the server and are transmitted

to GitHub Actions secrets

. This makes it possible to execute commands via SSH.

The second pair is needed solely for performance git clone in our script, you can copy the repository without entering a password only using SSH access. We will add the key from the second pair to the GitHub settings later.

This is quite a confusing moment, but you can handle it.

Script for updating the application

We sorted out the server. Now let's write a Bash script that will perform the entire application update process. Let's call him

deploy.sh

:

#!/bin/bash
# Stop on error
set -e
# Load nvm
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Move to folder with the apps from the github
cd /root
# Clone the repo
git clone <your-git-repo-link>
# Move to specific repo
cd /root/<name-of-repo>
# Install Node.js
nvm install
# Check node version
node -v
# Check npm version
npm -v
# Install dependencies
npm ci
# Build application
npm build
# Move build to the www folder
cp -rf /root/<your-project-name>/dist/* /var/www/default
# Remove repo
rm -rf /root/<your-project-name>

The script is commented in detail – it’s easy to figure out what’s happening.

Setting up GitHub Actions

Let's create a new file

.github/workflows/deploy-frontend.yml

:

name: Deploy
on:
  push:
    branches: [dev]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Set up SSH
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      - name: Run bash script via ssh
        run: |
          ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} "bash ${{ secrets.PATH_TO_SCRIPT }}"
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

At the first step, we “explain” to the action how to work with SSH, and also pass the private key as a parameter. On the second, we connect to the server and run the previously written script

deploy.sh

.

But what key should I add? From the first pair or the second? It's simple. We add the key from the first pair to secrets – the private key on the local machine. And don’t forget to open access in the GitHub account settings – indicate the public key from the second pair created on the server.

To add variables to GitHub Actions secrets, you need to go to the repository page and then use the menu: SettingsSecrets and variablesActionsNew repository secret.

3. Automatic backend deployment

Preparing the server

Let's use PM2 – a convenient process manager for

Node.js

which simplifies the management and monitoring of server applications:

npm install -g pm2

Setting up GitHub Actions

Here we will go a slightly different way (this was done on purpose to show different possible options). Let's create a file

.github/workflows/deploy-backend.yml

:

name: Deploy Backend
on:
  push:
    branches: [dev]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
            - name: Copy files to VPS
              uses: appleboy/scp-action@v0.1.0
              with:
                host: ${{ secrets.VPS_HOST }}
                username: ${{ secrets.VPS_USER }}
                key: ${{ secrets.SSH_PRIVATE_KEY }}
                source: './*'
                target: '</path/to/your/app>'
            - name: Restart PM2
              uses: appleboy/ssh-action@v0.1.0
              with:
                host: ${{ secrets.VPS_HOST }}
                username: ${{ secrets.VPS_USER }}
                key: ${{ secrets.SSH_PRIVATE_KEY }}
                script: |
                  cd </path/to/your/app>
                  nvm use
                  npm install
                  npm run build
                  pm2 start <your-app-name>

In this manual we say the following.

  1. Get access to our repository.
  2. Copy everything from the repository to the server.
  3. Execute the commands on the server: go to the project folder, install the node and dependencies, run the build using PM2.

Conclusion

GitHub Actions is a useful tool that can greatly simplify and speed up your development processes. We looked at three key automation scenarios: code review, front-end and back-end delivery. Using these examples, you can customize the scripts to suit your specific needs. A

Shared Line cloud servers

allow you to reduce project maintenance costs. Payment is made only for consumed power – according to the pay-as-you-go model.

Don't forget that to work with secrets (SERVER_IP, SERVER_USER, SERVER_SSH_KEY) you need to make the appropriate settings in the repository on GitHub. This approach will ensure data security.

We hope the article was useful to you. If it wasn't clear enough, take a look YouTube video. And if you have any questions, don’t hesitate to ask them in the comments or Telegram channel. Good luck with your projects!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *