Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# GitHub Actions Workflows

This directory contains the GitHub Actions workflow definitions for the
`data_services_api` gem. These workflows automate code quality checks, testing,
and release processes.

## Workflows Overview

| Workflow | File | Trigger | Purpose |
| --- | --- | --- | --- |
| Unit Tests | `unit-tests.yml` | Push to main, pull request to main, manual, workflow call | Runs the test suite and linting checks |
| Rubocop | `rubocop.yml` | Push to main, pull request to main, manual, workflow call | Checks code style compliance |
| Release and Publish | `publish.yml` | Manual dispatch | Gates on lint and tests, then builds, releases, and publishes the gem |

---

## Unit Tests (`unit-tests.yml`)

**Triggers:**

- Automatically on push and pull request to `main`
- Manually via the Actions UI or API
- Called directly by `publish.yml` as a required quality gate

**Purpose:** Installs dependencies, then runs linting and the test suite via
`make checks` to ensure code changes do not break existing functionality or
introduce style violations.

### Steps

1. Checks out the repository code with full git history
2. Detects the required Ruby version from `.ruby-version`
3. Sets up the Ruby environment
4. Installs dependencies via `make assets`
5. Runs linting and tests via `make checks`

### Notes

- The `EPI_GPR_READ_ACCESS_TOKEN` secret is required when called as a reusable
workflow, to authenticate with the Epimorphics GitHub Package Registry
- Push and pull request triggers are restricted to `main` to prevent duplicate
runs when a PR is open

---

## Rubocop Compliance (`rubocop.yml`)

**Triggers:**

- Automatically on push and pull request to `main`
- Manually via the Actions UI or API
- Called directly by `publish.yml` as a required quality gate

**Purpose:** Enforces Ruby code style and linting standards using Rubocop to
maintain consistent code quality across the project.

### Steps

1. Checks out the repository code
2. Sets up the Ruby environment
3. Installs dependencies via `make assets`
4. Runs Rubocop with GitHub-formatted output

### Notes

- The workflow will fail if any Rubocop offences are detected
- Ensure code passes locally with `bundle exec rubocop` before pushing

---

## Release and Publish Gem (`publish.yml`)

**Trigger:** Manual dispatch only (via GitHub Actions UI or API).

**Purpose:** Runs Rubocop compliance and the unit test suite as parallel quality
gates, then creates a GitHub release and publishes the gem to the GitHub Package
Registry. Publishing is restricted to the `main` branch; dispatching from
another branch runs the gates without releasing.

### Jobs

**`verify-rubocop`** — Calls `rubocop.yml` as a reusable workflow. The publish
job will not proceed unless this completes successfully.

**`verify-unit-tests`** — Calls `unit-tests.yml` as a reusable workflow. The
publish job will not proceed unless this completes successfully.

**`publish`** — Calls the shared
[`epimorphics/github-workflows`](https://github.com/epimorphics/github-workflows)
reusable workflow. Restricted to `main`; skipped silently on all other branches.

### Publish steps (via shared workflow)

1. Checks out the repository with full git history
2. Detects the required Ruby version from `.ruby-version`
3. Sets up the Ruby environment
4. Extracts gem name, owner, and version via `make tags`
5. Builds the gem package via `make gem`
6. Creates a GitHub release with auto-generated release notes
7. Publishes the gem to the GitHub Package Registry via `make publish`

### Prerequisites

- Update the version in `lib/data_services_api/version.rb`
- Update `CHANGELOG.md` with release notes
- Ensure the commit to release from is on `main`

### How to Trigger

1. Navigate to the **Actions** tab in GitHub
2. Select **Release and Publish Gem** from the workflow list
3. Click **Run workflow**
4. Select the branch (publishing will only proceed if `main` is selected)
5. Click the green **Run workflow** button

### Outputs

- A new GitHub release tagged with the version number
- The `.gem` file attached to the release
- The gem published to the GitHub Package Registry

---

## Troubleshooting

### Tests Failing

- Ensure all dependencies are installed: `make assets`
- Check that the Ruby version matches `.ruby-version`
- Verify your PAT is configured for the Epimorphics GitHub Package Registry

### Rubocop Failing

- Run `bundle exec rubocop -a` to auto-correct safe offences
- Review the Rubocop output for specific violations

### Publish Workflow Failing

- Verify the version number is correctly set in `version.rb`
- Confirm the workflow was dispatched from `main`
- Check that no release already exists for the target version

---

## Local Development

For setup instructions, available `make` targets, and guidance on running tests
and linting locally, see the [project README](../../README.md).
56 changes: 18 additions & 38 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,22 @@
name: Release and Publish Gem

on:
workflow_dispatch: {}
workflow_dispatch:

#---- Below this line should not require editing ----
jobs:
build:
name: "Build gem package"
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: "Git Information"
id: gitinfo
run: |
echo name=${GITHUB_REF#refs/*/} | tee -a $GITHUB_OUTPUT
echo branch=${GITHUB_REF#refs/heads/} | tee -a $GITHUB_OUTPUT
make tags | tee -a $GITHUB_OUTPUT

- name: "Build gem"
run: "make gem"

- name: "Create Release"
id: release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.gitinfo.outputs.version }}
name: v${{ steps.gitinfo.outputs.version }}
generate_release_notes: true
draft: false
prerelease: false
files: |
data_services_api-${{ steps.gitinfo.outputs.version }}.gem

- name: "Publish gem"
run: |
PAT=${{ secrets.GITHUB_TOKEN }} make publish
verify-rubocop:
uses: ./.github/workflows/rubocop.yml
verify-unit-tests:
uses: ./.github/workflows/unit-tests.yml
secrets:
EPI_GPR_READ_ACCESS_TOKEN: ${{ secrets.EPI_GPR_READ_ACCESS_TOKEN }}
publish:
needs:
- verify-rubocop
- verify-unit-tests
# Tests always run; publishing is intentionally restricted to main.
# Dispatching from another branch lets you verify the gate without releasing.
if: github.ref == 'refs/heads/main'
uses: epimorphics/github-workflows/.github/workflows/publish-gem.yml@v1
secrets:
github_pat: ${{ secrets.GITHUB_TOKEN }}
20 changes: 16 additions & 4 deletions .github/workflows/rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
name: Check Rubocop compliance

on: [push, pull_request]
# Restricting push to specific branches avoids duplicate runs when a PR
# is open; manual dispatch supports ad hoc checks; workflow_call lets
# publish.yml gate releases on lint passing.

on:
workflow_call:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6

- name: Set up Ruby
uses: ruby/setup-ruby@v1

- name: Install dependencies (bundle)
run: bundle install
run: make assets

- name: Run Rubocop
run: rubocop
run: rubocop --format github
47 changes: 37 additions & 10 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
name: Unit Tests
# Restricting push to specific branches prevents duplicate runs when a PR
# is open - without this, both push and pull_request fire on every commit.

on: [push, pull_request]
on:
workflow_call:
secrets:
EPI_GPR_READ_ACCESS_TOKEN:
required: true
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up Ruby
uses: ruby/setup-ruby@v1
- name: "Record desired ruby version"
id: ruby
shell: bash
run: |
[ -f .ruby-version ] && echo version=$(cat .ruby-version) | tee -a $GITHUB_OUTPUT || echo "version=" >> $GITHUB_OUTPUT

- name: Install dependencies (bundle)
run: bundle install
- name: "Setup ruby"
if: steps.ruby.outputs.version != ''
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ steps.ruby.outputs.version }}

- name: Run tests
run: rake test
env:
API_URL: http://localhost:8888
- name: Install dependencies (bundle)
run: make assets

- name: Run checks
# Passing the token via env rather than interpolating it directly into
# the run string prevents it from appearing in logs or process listings.
env:
PAT: ${{ secrets.EPI_GPR_READ_ACCESS_TOKEN }}
run: make checks
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- Adopted shared reusable workflow for gem publishing via GitHub Actions
- Added Rubocop compliance as a required gate before publishing
- Extended unit test and Rubocop workflows with manual dispatch and reusable
call support
- Scoped push and pull request triggers to the main branch to prevent duplicate
CI runs
- Standardised build flow to orchestrate verification, packaging, and cleaning
as a single step
- Documented Makefile target intent and the separation of verification,
packaging, and publishing
- Added GitHub Actions workflows README covering trigger behaviour and the
release process
- Updated gem publishing instructions to reflect the current Makefile and CI
pipeline
- Updated dev and maintenance dependencies to latest versions

## 1.6.1 - 2025-11

### Security
Expand Down
Loading