Part 1: Introduction to GitHub Actions and First Workflow

Introduction

I still remember the frustration of manually deploying my first TypeScript microservice. Every deployment involved:

  1. SSH into the server

  2. Pull the latest code

  3. Run npm install

  4. Run tests (and hope they pass)

  5. Build the project

  6. Restart the service

  7. Check logs to ensure it's working

This process took 15-20 minutes and was error-prone. I once deployed broken code to production because I forgot to run tests locally. That's when I discovered GitHub Actions, and it transformed how I work. Now, every push triggers automated tests, builds, and deploymentsβ€”all without my intervention.

In this part, I'll introduce you to GitHub Actions and help you create your first workflow for a TypeScript microservice.

What is GitHub Actions?

GitHub Actions is GitHub's built-in CI/CD (Continuous Integration/Continuous Deployment) platform. It allows you to automate workflows directly in your GitHub repository.

What Can You Automate?

From my experience, here's what I automate with GitHub Actions:

Development Workflows:

  • Run tests on every push

  • Lint code for style violations

  • Type-check TypeScript

  • Run security scans

Build and Package:

  • Build TypeScript to JavaScript

  • Create Docker images

  • Publish npm packages

  • Generate documentation

Deployment:

  • Deploy to staging on merge to develop

  • Deploy to production on release tags

  • Database migrations

  • Rollback on failure

Maintenance:

  • Auto-update dependencies

  • Close stale issues

  • Label pull requests

  • Generate release notes

Core Concepts

1. Workflows

A workflow is an automated process defined in a YAML file stored in .github/workflows/ in your repository.

Example: .github/workflows/ci.yml

2. Events

Events trigger workflows. Common events I use:

  • push: Code is pushed to repository

  • pull_request: PR is opened/updated

  • release: New release is published

  • schedule: Run on a schedule (cron)

  • workflow_dispatch: Manual trigger

3. Jobs

A workflow contains one or more jobs that run in parallel (by default) or sequentially.

4. Steps

Steps are individual tasks within a job. They run sequentially.

5. Runners

Runners are servers that execute your workflows. GitHub provides:

  • ubuntu-latest (most common for Node.js)

  • windows-latest

  • macos-latest

You can also use self-hosted runners.

6. Actions

Actions are reusable units of code. You can use actions from:

  • GitHub Marketplace (actions/checkout@v3)

  • Your own repository

  • Other repositories

My First Workflow: A Real Example

When I started my TypeScript payment service, this was my first workflow:

Project Structure

The First Workflow

What This Workflow Does

When I push code or open a PR:

  1. Checks out my code using actions/checkout@v3

  2. Sets up Node.js 18 using actions/setup-node@v3

  3. Installs dependencies with npm ci (faster and more reliable than npm install)

  4. Lints the code to catch style issues

  5. Type checks to catch TypeScript errors

  6. Runs tests to ensure functionality

If any step fails, the workflow stops and I get a notification.

Creating Your First Workflow

Let's create a workflow for a TypeScript microservice step by step.

Step 1: Prepare Your Project

package.json scripts:

Step 2: Create Workflow Directory

Step 3: Create Workflow File

Step 4: Write the Workflow

Step 5: Commit and Push

Step 6: Watch It Run!

  1. Go to your GitHub repository

  2. Click on Actions tab

  3. You'll see your workflow running

Understanding the Workflow Output

When the workflow runs, you'll see:

If any step fails:

Real-World Example: My Payment Service Workflow

Here's the actual workflow I use for my payment processing microservice:

What makes this workflow production-ready:

  1. PostgreSQL service container for integration tests

  2. Prisma migrations run before tests

  3. Separate unit and integration tests

  4. Secrets management for API keys

  5. Coverage reporting with Codecov

  6. Environment variables for configuration

Common Workflow Triggers

Push to Specific Branches

Pull Request Events

Scheduled Workflows (Cron)

I use this for:

  • Dependency update checks

  • Database backup jobs

  • Cleanup old artifacts

Manual Triggers

Multiple Events

Viewing Workflow Results

Success

When everything passes:

Failure

When something fails:

GitHub Status Checks

I configure branch protection to require:

Now PRs can't be merged until workflows pass!

My Workflow Development Process

1. Start Simple

2. Add Gradually

3. Optimize

4. Refine

Debugging Workflows

Enable Debug Logging

In your repository settings:

Then re-run the workflow to see detailed logs.

Common Issues I've Faced

Issue 1: Tests Pass Locally but Fail in CI

Issue 2: Slow Workflow

Issue 3: Integration Tests Fail

Best Practices from Experience

1. Use npm ci Instead of npm install

2. Cache Dependencies

3. Fail Fast

4. Use Descriptive Names

5. Organize Steps Logically

Conclusion

GitHub Actions transforms how we develop and deploy software. In this part, we covered:

  • What GitHub Actions is and why it's valuable

  • Core concepts: workflows, jobs, steps, runners, actions

  • Creating your first CI workflow for a TypeScript microservice

  • Real-world examples from production projects

  • Common triggers and debugging techniques

  • Best practices for workflow development

With this foundation, you can now automate testing for your TypeScript projects. Every push triggers automated checks, catching bugs before they reach production.

In Part 2, we'll dive deep into YAML syntax and workflow fundamentals, exploring all the configuration options available in GitHub Actions workflows.


Key Takeaways:

  • Workflows are YAML files in .github/workflows/

  • Start simple and add features gradually

  • Use npm ci and caching for speed

  • Service containers enable integration testing

  • Branch protection ensures workflows pass before merging

Remember: The best time to set up CI/CD was at the start of your project. The second-best time is now! πŸš€

Last updated