diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..850b85d --- /dev/null +++ b/.github/workflows/README.md @@ -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). diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 401fa70..a6fa5e9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -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 }} diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index aa3cf1c..05976d4 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -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 diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index d472f4c..720660a 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e3b9da..0ae96be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..7a711f2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,127 @@ +# Contributing to data-services-api + +This guide covers development workflow for the data-services-api gem. + +## Getting Started + +After cloning the repository: + +### Install Dependencies + +```sh +make assets +``` + +This installs all required gems via Bundler. + +### GitHub Package Registry Authentication + +This gem is published to the Epimorphics GitHub Package Registry. This allows us +to publish and use Rubygems that we create in our own apps without publishing +via the public `rubygems.org` or wiring in direct references to GitHub repos in +our `Gemfile`s. + +Access to the GitHub package registry is authorised via a _personal access +token_ (PAT). There are [instructions on the Epimorphics wiki](https://github.com/epimorphics/internal/wiki/Ansible-CICD#creating-a-pat-for-gpr-access) +for creating a new PAT if you don't have one. Once created, the same PAT can be +reused across projects. + +#### For Users (Fetching the Gem) + +To use this gem in another Ruby project, authenticate Bundler: + +```sh +bundle config set --global https://rubygems.pkg.github.com/epimorphics USERNAME:TOKEN +``` + +Replace `USERNAME` with your GitHub username and `TOKEN` with your personal +access token. + +#### For Developers (Working on the Gem) + +Running `make auth` will prompt for your PAT and write it to `~/.gem/credentials`: + +```sh +make auth +``` + +The same mechanism is used by the CI publication workflow, where the PAT is +supplied automatically via `secrets.GITHUB_TOKEN`. + +## Development Workflow + +### `Makefile` Commands + +The project includes a `Makefile` with common development tasks: + +- `make assets` — Install gem dependencies via Bundler +- `make auth` — Create GitHub and Bundler authorisations +- `make build` — Verify and build the gem (runs `clean`, `checks`, then `gem`) +- `make check` — Alias for `checks` +- `make checks` — Run linting and tests +- `make gem` — Build the gem artefact only +- `make lint` — Run Rubocop linting +- `make publish` — Push an existing gem artefact to the GitHub Package Registry +- `make tags` — Display version information for the CI pipeline +- `make test` — Run the test suite +- `make updates` — Check for outdated Ruby gems + +The Makefile separates verification, packaging, and publishing so each stage can +be run independently and composed safely. CI enforces quality gates before +publishing, whilst local workflows can run verification and packaging together or +independently. + +### Linting + +Rubocop should not report any warnings: + +```sh +$ make lint +Inspecting 21 files +..................... + +21 files inspected, no offenses detected +``` + +`make lint` runs Rubocop with safe auto-correction (`-a`) for local developer +convenience. The CI workflow runs Rubocop without auto-correction and will fail +when offences are detected. + +### Tests + +You will need to have started the [HMLR Data API](https://github.com/epimorphics/lr-data-api) +locally. Follow the instructions in the repository's [README](https://github.com/epimorphics/lr-data-api#run). + +Once the API is running, invoke the tests with: + +```sh +make test +``` + +You can also set the environment variable `API_SERVICE_URL` to point to a +running instance on a non-default port: + +```sh +API_SERVICE_URL=http://localhost:8080 make test +``` + +> [!NOTE] +> If `API_SERVICE_URL` is not set it defaults to `http://localhost:8888`. + +## Publishing a New Version + +To publish a new version of the gem after a bugfix or feature addition: + +1. Make the required code changes and have them reviewed +2. Update `CHANGELOG.md` to document the new change +3. Update `lib/data_services_api/version.rb` following semantic versioning +4. Run `make build` locally to verify linting and tests pass before releasing +5. Merge the changes to `main` +6. Trigger the **Release and Publish Gem** workflow manually via the GitHub + Actions UI — see the [workflows README](.github/workflows/README.md) for + full instructions + +The workflow runs Rubocop and the test suite as parallel quality gates before +publishing. The gem will appear on the [list of +releases](https://github.com/epimorphics/data_services_api/releases) once +complete. diff --git a/Gemfile b/Gemfile index 50f09e0..b581adf 100644 --- a/Gemfile +++ b/Gemfile @@ -5,11 +5,22 @@ source 'https://rubygems.org' # Specify the gem's runtime dependencies in data_services_api.gemspec gemspec -gem 'byebug', group: %i[development test], require: false +# Development dependencies are mirrored here to make them "explicit" for bundler. +# This allows `bundle outdated --only-explicit` to check these dependencies, +# which would otherwise be treated as sub-dependencies from the gemspec. +group :maintenance do + gem 'faraday', '~> 2.13', '>= 2.13.0' + gem 'faraday-encoding', '~> 0.0', '>= 0.0.6' + gem 'faraday-follow_redirects', '~> 0.4', '>= 0.4.0' + gem 'faraday-retry', '~> 2.0', '>= 2.0' + gem 'json', '~> 2.0' + gem 'yajl-ruby', '~> 1.4' +end # Add development dependencies here though as they are not required to run the gem group :development, :test do gem 'bundler' + gem 'byebug', platforms: %i[mri windows], require: false gem 'excon' gem 'json_expressions' gem 'minitest' @@ -23,3 +34,7 @@ group :development, :test do gem 'simplecov', require: false gem 'webmock' end + +group :development do + gem 'foreman' +end diff --git a/Gemfile.lock b/Gemfile.lock index b28cb1b..e469068 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,6 +36,8 @@ GEM net-http (~> 0.5) faraday-retry (2.3.2) faraday (~> 2.0) + foreman (0.90.0) + thor (~> 1.4) hashdiff (1.2.1) json (2.16.0) json_expressions (0.9.0) @@ -90,6 +92,7 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) + thor (1.5.0) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) unicode-emoji (4.1.0) @@ -111,6 +114,12 @@ DEPENDENCIES byebug data_services_api! excon + faraday (~> 2.13, >= 2.13.0) + faraday-encoding (~> 0.0, >= 0.0.6) + faraday-follow_redirects (~> 0.4, >= 0.4.0) + faraday-retry (~> 2.0, >= 2.0) + foreman + json (~> 2.0) json_expressions minitest minitest-rg @@ -122,6 +131,7 @@ DEPENDENCIES rubocop simplecov webmock + yajl-ruby (~> 1.4) BUNDLED WITH 2.7.2 diff --git a/Makefile b/Makefile index ea1ad5d..e6b7dae 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,17 @@ -.PHONY: auth clean gem publish test +.PHONY: all auth build bundles check checks clean coverage docs forceclean gem help lint publish realclean rubocop tag tags test updates vars version -NAME?=data_services_api +GEM_NAME?=data_services_api OWNER?=epimorphics -VERSION?=$(shell ruby -e 'require "./lib/${NAME}/version" ; puts DataServicesApi::VERSION') +COMMIT=$(shell git rev-parse --short HEAD) +VERSION?=$(shell /usr/bin/env ruby -e 'require "./lib/${GEM_NAME}/version" ; puts DataServicesApi::VERSION') +TAG?=${VERSION}-${COMMIT} PAT?=$(shell read -p 'Github access token:' TOKEN; echo $$TOKEN) +BUNDLE?=bundle AUTH=${HOME}/.gem/credentials -GEM=${NAME}-${VERSION}.gem +GEM=${GEM_NAME}-${VERSION}.gem GPR=https://rubygems.pkg.github.com/${OWNER} -SPEC=${NAME}.gemspec +SPEC=${GEM_NAME}.gemspec ${AUTH}: @mkdir -p ${HOME}/.gem @@ -16,86 +19,91 @@ ${AUTH}: @echo ':github: Bearer ${PAT}' >> ${AUTH} @chmod 0600 ${AUTH} -${GEM}: ${SPEC} ./lib/${NAME}/version.rb +# Build the gem package +${GEM}: ${SPEC} ./lib/${GEM_NAME}/version.rb gem build ${SPEC} -all: publish +all: check ## Default target: run all checks assets: - @echo "Installing assets for ${NAME} gem..." + @echo "Installing assets for ${GEM_NAME} gem..." @bundle install - @echo "Assets for ${NAME} gem are up to date." + @echo "Assets for ${GEM_NAME} gem are up to date." -auth: ${AUTH} +auth: ${AUTH} ## Set up authentication for GitHub and Bundler + @echo "Authentication set up for GitHub and Bundler." -build: clean gem +build: clean checks gem ## Verify and build the gem + @echo "Build and verification complete." -checks: lint test +check: checks ## Alias for checks target -clean: - @echo "Cleaning up ${NAME} gem..." +checks: lint test ## Run all checks: linting and tests + @echo "All checks passed." + +clean: ## Remove generated files + @echo "Cleaning up..." @bundle exec rake clean clobber - @rm -rf ${GEM} + @rm -rf coverage doc *.gem + +coverage: ## Display test coverage report + @open coverage/index.html + @echo "Displaying test coverage report in browser..." + +forceclean: realclean ## Remove all bundled files and reset Bundler + @${BUNDLE} clean --force || : -gem: ${GEM} +gem: ${GEM} ## Build the gem package @echo ${GEM} -help: - @echo "Make targets:" - @echo " all - build the Docker image (default)" - @echo " assets - install gems and yarn packages, compile assets" - @echo " auth - compile the required package registry authorisations" - @echo " build - build the gem package" - @echo " checks - run all linting and tests as a single task" - @echo " clean - remove temporary files" - @echo " gem - show the gem file name" - @echo " help - show this help message" - @echo " lint - run linters" - @echo " publish - release the image to the Docker registry" - @echo " realclean - remove all authentication tokens" - @echo " tags - show the current name, owner and version tags" - @echo " test - runs the test suite, be it units or integration" - @echo " vars - show the current variable settings" - @echo " version - show the current version" +help: ## Display this message + @echo "Available make targets:" + @grep -hE '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-20s %s\n", $$1, $$2}' @echo "" - @echo "Environment variables (optional: all variables have defaults):" - @echo " GEM - package name of the gem file (default: ${NAME}-${VERSION}.gem)" - @echo " GPR - GitHub package registry for gem (default: from git config)" - @echo " NAME - name of the Gem (default: from deployment.yaml)" - @echo " PAT - GitHub personal access token (default: prompt)" - @echo " SPEC - gemspec file to use (default: ${NAME}.gemspec)" - @echo " VERSION - version of the application (default: from VERSION file)" - -lint: - @echo "Running code linting for ${NAME} ..." -# Auto-correct offenses safely where possible with the `-a` flag - @bundle exec rubocop -a - @echo "Linting checks completed." - -publish: ${AUTH} ${GEM} - @echo Publishing package ${NAME}:${VERSION} to ${OWNER} ... - @gem push --key github --host ${GPR} ${GEM} - @echo Done. - -realclean: clean - @rm -rf ${AUTH} - -tags: - @echo name=${NAME} - @echo owner=${OWNER} - @echo version=${VERSION} + @make vars + +lint: rubocop ## Run linting checks + @echo "Linting complete." -test: assets gem - @bundle exec rake test - @echo "Tests completed successfully." +publish: ${AUTH} ${GEM} ## Publish the gem to the GitHub Package Registry + @echo "Publishing ${GEM} to GitHub Package Registry..." + @gem push --key github \ + --host ${GPR} ${GEM} + @echo "Done." -vars: - @echo "GEM=${GEM}" - @echo "GPR=${GPR}" - @echo "NAME=${NAME}" - @echo "OWNER=${OWNER}" - @echo "SPEC=${SPEC}" - @echo "VERSION=${VERSION}" +realclean: clean ## Remove all generated files and authentication + @echo "Removing authentication..." + @rm -f ${AUTH} + +rubocop: ## Run RuboCop linting + @echo "Running RuboCop linting..." + @${BUNDLE} exec rubocop -a + +tag: ## Display the current gem tag + @echo ${TAG} + +tags: ## Display version information for CI pipeline + @echo name=${GEM_NAME} + @echo owner=${OWNER} + @echo version=${VERSION} -version: +test: assets ## Run the test suite + @echo "Running tests..." + @${BUNDLE} exec rake test + +updates: ## Check for outdated Ruby gems with Bundler + @echo "Running bundle outdated to check Ruby gems..." + @${BUNDLE} outdated --only-explicit || true + +vars: ## Display current variable values + @echo "COMMIT = ${COMMIT}" + @echo "GEM = ${GEM}" + @echo "GEM_NAME = ${GEM_NAME}" + @echo "GPR = ${GPR}" + @echo "OWNER = ${OWNER}" + @echo "SPEC = ${SPEC}" + @echo "TAG = ${TAG}" + @echo "VERSION = ${VERSION}" + +version: ## Display the gem version @echo ${VERSION} diff --git a/README.md b/README.md index b1aadab..0102b8d 100644 --- a/README.md +++ b/README.md @@ -56,76 +56,41 @@ order for the gem to work._ --- -## Developer notes +## Incident triage: is this gem a likely cause of any alarms? -### Linting +This gem is a shim layer. It translates DsAPI query expressions into Sapi-NT +requests and normalises the returned JSON. It has no data store and no logic of +its own beyond that translation. -Rubocop should not report any warnings: +Likely: -```sh -$ make lint -Inspecting 21 files -..................... +- Queries that previously returned results now return errors or empty responses + and a Sapi-NT change is suspected +- Response field mapping or JSON structure changed unexpectedly after a gem + version update -21 files inspected, no offenses detected -``` - -### Tests +Less likely: -You will need to have started the [HMLR Data -API](https://github.com/epimorphics/lr-data-api) locally. To do so follow the -instructions in the repository's -[README](https://github.com/epimorphics/lr-data-api#run) +- Upstream Sapi-NT service is unavailable or returning 5xx responses +- Network connectivity between the consuming application and the API endpoint + is degraded +- Data pipeline issues upstream of Sapi-NT -Once the API is started you can invoke the tests with the simple command -below[^1]: - -```sh -make test -``` +> [!NOTE] +> The test suite uses VCR cassettes to mock upstream responses. A passing test +> run confirms the shim logic is intact but does **not** confirm the upstream +> service is healthy. To verify Sapi-NT directly, check `API_SERVICE_URL` in the +> consuming application's environment and issue a request against it independently. -You can also set the environment variable `API_URL` to point to a running -instance of the HMLR Data API from a non-default port: +--- -```sh -API_URL=http://localhost:8080 make test -``` +## Contributing -_N.B If `API_URL` environment variable is not set it will default to -`http://localhost:8888`_ +For setup instructions, available `make` targets, running tests, linting, and +publishing releases, see [CONTRIBUTING.md](CONTRIBUTING.md). --- -### Publishing the gem to the Epimorphics GitHub Package Registry - -This gem is now published to the Epimorphics section of the GitHub Package -Registry (GPR). Previously we linked directly to the GitHub repo in the -`Gemfile`s of applications consuming this library, but this practice is now -anti-preferred. - -Note that in order to publish to the Epimorphics section of the GPR, you'll need -a GitHub personal access token (PAT). There are [instructions on the Epimorphics -wiki](https://github.com/epimorphics/internal/wiki/Ansible-CICD#creating-a-pat-for-gpr-access) -for creating a new PAT if you don't have one. Once created, you can use the same -PAT in multiple projects, you don't need to create a new one each time. - -At present, publishing is a manual step for Gem maintainers. The process is: - -1. Make the required code changes, and have them reviewed by other members of - the team -2. Update `CHANGELOG.md` with the changes. Update - `lib/data_services_api/version.rb` following semantic version principles -3. Check that the gem builds correctly via the `make gem` target - - This will run the tests and build the gem locally; however, the local gem - will be ignored by the `.gitignore` file and not included in the recorded - code changes in the repository. -4. Push the changes to the `main` branch via a pull request -5. On PR merge, create a new release in GitHub by triggering the `Publish` - GitHub Action workflow manually. -6. Check on the [GitHub Package - Registry](https://github.com/orgs/epimorphics/packages?repo_name=data_services_api) - to see that the new gem has been published. - ### Prometheus monitoring This gem integrates with Prometheus monitoring by emitting the following @@ -135,6 +100,3 @@ This gem integrates with Prometheus monitoring by emitting the following - `connection_failure.api` - failure to connect to the API, with exception detail - `service_exception.api` - failure to process the API response - -[^1]: You may need to preface the `rake test` command with `bundle exec` if you - are using a Ruby version manager such as `rbenv` or `rvm`.