diff --git a/.github/workflows/container.yaml b/.github/workflows/container.yaml new file mode 100644 index 0000000..22d9669 --- /dev/null +++ b/.github/workflows/container.yaml @@ -0,0 +1,61 @@ +--- +name: Publish OCI Container +on: # yamllint disable-line rule:truthy + workflow_call: + inputs: + tag: + description: 'The tag to use for the container image' + required: false + type: string + workflow_dispatch: + inputs: + tag: + description: 'The tag to use for the container image' + required: false + type: string +jobs: + publish_github: + name: Publish the container image to GitHub Container Registry + runs-on: ubuntu-latest + strategy: + # Go hard on the builders + max-parallel: 5 + matrix: + alpine-version: ['3.20'] + ruby-version: ['3.4.1'] + steps: + - + name: Checkout repository + uses: actions/checkout@v4 + - + name: Publish to ghcr.io + env: + ALPINE_VERSION: ${{ matrix.alpine-version }} + REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RUBY_VERSION: ${{ matrix.ruby-version }} + TAG: ${{ github.event.inputs.tag || '' }} + TRACE: ${{ secrets.ACTIONS_STEP_DEBUG || 'false' }} + # yamllint disable rule:line-length + run: | + if [ -z "$TAG" ] + then + [ "$TRACE" = true ] && printf 'No tag provided, getting tag from .version.txt\n' >&2 + if [ -f ".version.txt" ] + then + version=$(<.version.txt) + else + [ "$TRACE" = true ] && printf 'No .version.txt found, getting version from git describe --tags --abbrev=0\n' >&2 + version=$(git describe --tags --abbrev=0) + fi + else + [ "$TRACE" = true ] && printf 'Using provided tag %s\n' "$TAG" >&2 + version=$TAG + fi + [ "$TRACE" = 'true' ] && printf 'Calling ./ci/build_image.sh -vvp "%s"\n' "$version" >&2 + IMAGE_NAME=$(basename "$GITHUB_REPOSITORY") \ + GITHUB_TOKEN=$REGISTRY_TOKEN \ + ALPINE_VERSION=$ALPINE_VERSION \ + RUBY_VERSION=$RUBY_VERSION \ + ./ci/build_image.sh -vvp "$version" + # yamllint enable rule:line-length + shell: bash diff --git a/.github/workflows/conventional_commits.yaml b/.github/workflows/conventional_commits.yaml new file mode 100644 index 0000000..25469a2 --- /dev/null +++ b/.github/workflows/conventional_commits.yaml @@ -0,0 +1,63 @@ +--- +name: Conventional Commits And PR titles + +on: # yamllint disable-line rule:truthy + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + comventional_commits: + name: Validate Commit Subjects + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: webiny/action-conventional-commits@v1.3.0 + name: Validate Commit Subjects + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # All of the Angular commit types are allowed by default. + # Added types to this: + # * eyes - For observability related changes + # * sec - For security related changes + allowed-commit-types: "build,chore,ci,docs,eyes,feat,fix,perf,refactor,revert,sec,style,test" # yamllint disable-line rule:line-length + conventional_pr_title: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + id: validate-pr-title + name: Validate PR title + uses: amannn/action-semantic-pull-request@v5 + with: + # All of the Angular commit types are allowed by default. + # Added types to this: + # * eyes - For observability related changes + # * sec - For security related changes + types: | + build + chore + ci + docs + eyes + feat + fix + perf + refactor + revert + sec + style + test + # We don't enforce scopes + # scopes: + # - frontend + # - backend + # - ci + # We don't disallow any scopes + # disallowScopes: | + # release + wip: true diff --git a/.github/workflows/gem.yaml b/.github/workflows/gem.yaml new file mode 100644 index 0000000..a2b161e --- /dev/null +++ b/.github/workflows/gem.yaml @@ -0,0 +1,34 @@ +--- +name: Publish Ruby Gem +on: # yamllint disable-line rule:truthy + workflow_call: + workflow_dispatch: +jobs: + publish_gem: + name: Publish the gem to registries + runs-on: ubuntu-latest + strategy: + matrix: + registry: + - key: rubygems + secret: RUBYGEMS_TOKEN + steps: + - + name: Checkout repository + uses: actions/checkout@v4 + - + name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.4.1 + bundler-cache: false + - + name: Publish to ${{ matrix.registry }} + env: + TRACE: ${{ secrets.ACTIONS_STEP_DEBUG || 'false' }} + GEM_TOKEN: ${{ secrets[matrix.registry.secret] }} + REGISTRY: ${{ matrix.registry.key }} + run: | + bundle install + TRACE="$TRACE" GEM_TOKEN="$GEM_TOKEN" ./ci/publish-gem.sh "$REGISTRY" + shell: bash diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000..fc8098c --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,32 @@ +name: Ruby + +on: + workflow_call: + + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + name: Ruby ${{ matrix.ruby }} + strategy: + matrix: + ruby: + - '3.4.5' + services: + nats: + image: nats:latest + ports: ["4222:4222", "6222:6222", "8222:8222"] + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: false + - name: Install dependencies + run: bundle install --jobs 4 --retry 3 + - name: Run the default task + run: bundle exec rake + env: + NATS_URI: nats://nats:4222 diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..adff340 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,17 @@ +--- +name: Publish + +on: # yamllint disable-line rule:truthy + workflow_dispatch: + workflow_call: + +jobs: + gem: + name: Build and publish gem + uses: ./.github/workflows/gem.yaml + secrets: inherit + +# containers: +# name: Build and publish OCI container images +# uses: ./.github/workflows/container.yaml +# secrets: inherit diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..6411443 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,51 @@ +--- +name: Release + +on: # yamllint disable-line rule:truthy + push: + branches: + - main + workflow_dispatch: + workflow_call: + +jobs: + validate: + name: Validations + uses: ./.github/workflows/validations.yaml + + release: + needs: [validate] + name: Create a release + runs-on: ubuntu-latest + outputs: + release_created: ${{ steps.release.outputs.release_created }} + steps: + - + uses: actions/checkout@v4 + id: git-checkout + with: + fetch-tags: true + - + uses: googleapis/release-please-action@v4 + id: release + with: + config-file: .release-please-config.json + manifest-file: .release-please-manifest.json + token: ${{ secrets.RELEASE_PLEASE_TOKEN }} + - + id: debug + env: + RELEASE_CREATED: ${{ steps.release.outputs.release_created }} + TRACE: ${{ secrets.ACTIONS_STEP_DEBUG || 'false' }} + run: | + if [ "$TRACE" != 'false' ] + then + printf 'Release created: %s\n' "$RELEASE_CREATED" + fi + + publish: + if: needs.release.outputs.release_created + needs: release + name: Build and publish artifacts + uses: ./.github/workflows/publish.yaml + secrets: inherit diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml new file mode 100644 index 0000000..bd9ea2c --- /dev/null +++ b/.github/workflows/validations.yaml @@ -0,0 +1,12 @@ +--- +name: Validations + +on: # yamllint disable-line rule:truthy + workflow_dispatch: + workflow_call: + pull_request: + +jobs: + validate_ruby: + name: Ruby Tests + uses: ./.github/workflows/main.yaml diff --git a/.release-please-config.json b/.release-please-config.json new file mode 100644 index 0000000..735db4a --- /dev/null +++ b/.release-please-config.json @@ -0,0 +1,32 @@ +{ + "packages": { + ".": { + "changelog-path": "CHANGELOG.md", + "release-type": "simple", + "bump-minor-pre-major": true, + "bump-patch-for-minor-pre-major": true, + "draft": false, + "prerelease": false, + "version-file": ".version.txt", + "extra-files": [ + { + "type": "generic", + "path": "lib/sequel/pgt_outbox/version.rb" + }, + { + "type": "generic", + "path": "oci/Gemfile" + } + ], + "exclude-paths": [ + ".release-please-manifest.json", + ".version.txt", + "lib/sequel/pgt_outbox/version.rb", + ".rubocop.yml", + ".overcommit.yml", + "coverage/coverage.json" + ] + } + }, + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" +} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..054e8bc --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.2.7" +} diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..822cddd --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,46 @@ +plugins: + - rubocop-performance + - rubocop-rake + - rubocop-minitest + +AllCops: + NewCops: enable + +Layout/LineLength: + Max: 140 + +Metrics/BlockLength: + Exclude: + - 'spec/**/*.rb' + +Layout/ArgumentAlignment: + EnforcedStyle: with_fixed_indentation + +Bundler/OrderedGems: + TreatCommentsAsGroupSeparators: true + +Layout/MultilineMethodCallIndentation: + EnforcedStyle: indented + +Layout/ArrayAlignment: + EnforcedStyle: with_fixed_indentation + +Style/Documentation: + Enabled: false + +Style/FrozenStringLiteralComment: + Enabled: true + SafeAutoCorrect: true + +Style/TrailingCommaInArguments: + EnforcedStyleForMultiline: comma + +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma + +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma + +Style/HashSyntax: + Enabled: true + EnforcedShorthandSyntax: always diff --git a/Gemfile b/Gemfile index 6cc549d..740c85d 100644 --- a/Gemfile +++ b/Gemfile @@ -12,5 +12,6 @@ gem 'rake' gem 'reline' gem 'rubocop' gem 'rubocop-minitest' +gem 'rubocop-performance' gem 'rubocop-rake' gem 'simplecov' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..af59bea --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,101 @@ +PATH + remote: . + specs: + leopard (0.1.0) + nats-pure (~> 2.5) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.3) + base64 (0.3.0) + coderay (1.1.3) + concurrent-ruby (1.3.5) + docile (1.4.1) + io-console (0.8.1) + json (2.13.1) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + method_source (1.1.0) + minitest (5.25.5) + minitest-global_expectations (1.0.1) + minitest (> 5) + nats-pure (2.5.0) + base64 + concurrent-ruby (~> 1.0) + json + securerandom + uri + parallel (1.27.0) + parser (3.3.9.0) + ast (~> 2.4.1) + racc + prism (1.4.0) + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + racc (1.8.1) + rainbow (3.1.1) + rake (13.3.0) + regexp_parser (2.10.0) + reline (0.6.2) + io-console (~> 0.5) + rubocop (1.79.0) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.46.0, < 2.0) + ruby-progressbar (~> 1.7) + tsort (>= 0.2.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.46.0) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-minitest (0.38.1) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-performance (1.25.0) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.38.0, < 2.0) + rubocop-rake (0.7.1) + lint_roller (~> 1.1) + rubocop (>= 1.72.1) + ruby-progressbar (1.13.0) + securerandom (0.4.1) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) + tsort (0.2.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) + uri (1.0.3) + +PLATFORMS + ruby + x86_64-linux + +DEPENDENCIES + leopard! + minitest + minitest-global_expectations + pry + rake + reline + rubocop + rubocop-minitest + rubocop-performance + rubocop-rake + simplecov + +BUNDLED WITH + 2.6.9 diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..91331ca --- /dev/null +++ b/Rakefile @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'rake' +require 'minitest/test_task' +require 'bundler/gem_tasks' +require 'rubocop/rake_task' + +RuboCop::RakeTask.new + +Minitest::TestTask.create(:test) do |task| + task.libs << 'lib' + task.libs << 'test' + task.test_globs = ['test/*/**/*.rb'] + task.warning = true +end + +task default: %i[rubocop test] diff --git a/ci/build_image.sh b/ci/build_image.sh new file mode 100755 index 0000000..3d044bd --- /dev/null +++ b/ci/build_image.sh @@ -0,0 +1,257 @@ +#!/usr/bin/env bash + +if readlink -f . >/dev/null 2>&1 # {{{ makes readlink work on mac +then + readlink=readlink +else + if greadlink -f . >/dev/null 2>&1 + then + readlink=greadlink + else + printf "You must install greadlink to use this (brew install coreutils)\n" >&2 + fi +fi # }}} + +# Set here to the full path to this script +me=${BASH_SOURCE[0]} +[ -L "$me" ] && me=$($readlink -f "$me") +here=$(cd "$(dirname "$me")" && pwd) +just_me=$(basename "$me") + +repo_top=$(git rev-parse --show-toplevel) +cd "$repo_top" || { + printf "Could not cd to %s\n" "$repo_top" >&2 + exit 1 +} + +base_dir=$(basename "$(pwd)") +: "${UBUNTU_VERSION:=bookworm}" +: "${BUILD_CONTEXT:=$(pwd)}" +: "${IMAGE_NAME:=$base_dir}" +: "${LICENSE:=MIT}" +: "${REGISTRY:=ghcr.io}" +: "${RUBY_VERSION:=3.3.6}" +: "${REGISTRY_TOKEN:=$GITHUB_TOKEN}" + +base_image_tag="$RUBY_VERSION-$UBUNTU_VERSION" +base_exists=$(skopeo list-tags docker://docker.io/ruby |jq -r "any(.Tags[] == \"$base_image_tag\"; .)") +if [ "$base_exists" = "false" ] +then + printf "Base image %s does not exist at docker.io/ruby, cannot build.\n" "$base_image_tag" >&2 + exit 99 +fi + +usage() { # {{{ + cat <<-EOT + Build an image, optionally pushing it to the registry + + Usage: $0 + Options: + -c CONTAINERFILE Path to the containerfile (default: ./oci/Containerfile) + -C CONTEXT Build context (default: $BUILD_CONTEXT) + -i NAME Name of the image (default: $IMAGE_NAME) + -l LICENSE License of the image (default: $LICENSE) + -r REGISTRY Registry to push the image to when -p is given (default: $REGISTRY) + -p Push the image to the registry + -h Show help / usage +EOT +} # }}} + +die() { # {{{ + local -i code + code=$1 + shift + error "$*" + printf "\n" >&2 + usage >&2 + # shellcheck disable=SC2086 + exit $code +} # }}} + +## Logging functions # {{{ +log() { # {{{ + printf "%s [%s] <%s> %s\n" "$(date '+%Y-%m-%d %H:%M:%S.%6N')" "$$" "${just_me:-$0}" "$*" +} # }}} + +debug() { # {{{ + [ $verbose -lt 2 ] && return 0 + # shellcheck disable=SC2059 + log_line=$(printf "$@") + log "[DEBUG] $log_line" >&2 +} # }}} + +warn() { # {{{ + # shellcheck disable=SC2059 + log_line=$(printf "$@") + log "[WARN] $log_line" >&2 +} # }}} + +error() { # {{{ + # shellcheck disable=SC2059 + log_line=$(printf "$@") + log "[ERROR] $log_line" >&2 +} # }}} + +info() { # {{{ + [ $verbose -lt 1 ] && return 0 + # shellcheck disable=SC2059 + log_line=$(printf "$@") + log "[INFO] $log_line" >&2 +} # }}} +# }}} + +push=0 +verbose=0 +while getopts :hpvc:C:i:l:r: opt # {{{ +do + case $opt in + c) + CONTAINERFILE=$OPTARG + ;; + C) + BUILD_CONTEXT=$OPTARG + ;; + i) + IMAGE_NAME=$OPTARG + ;; + l) + LICENSE=$OPTARG + ;; + r) + REGISTRY=$OPTARG + ;; + p) + push=1 + ;; + v) + verbose=$((verbose + 1)) + ;; + h) + usage + exit + ;; + :) + printf "Option %s requires an argument\n" "$OPTARG" >&2 + usage >&2 + exit 28 + ;; + ?) + printf "Invalid option '%s'\n" "$OPTARG" >&2 + usage >&2 + exit 27 + ;; + esac +done # }}} +shift $((OPTIND-1)) + +tag=$1 +[ -z "$tag" ] && die 1 "Missing image tag" +shift + +# Check for extra argument +if [ $# -gt 0 ]; then + # If we have the special argument '--' we shift it away, otherwise we die + [ "$1" != '--' ] && die 2 "Too many arguments" + # Once this is shifted away, the rest of the arguments are passed to the build command, below + shift +fi + +if [ -z "$CONTAINERFILE" ]; then + printf "No containerfile specified, looking for default locations\n" + for containerfile in Containerfile Dockerfile + do + if [ -f ./oci/"$containerfile" ]; then + debug "Found ./oci/%s\n" "$containerfile" + containerfile=./oci/"$containerfile" + break + fi + if [ -f "$containerfile" ]; then + debug "Found %s\n" "$containerfile" + break + fi + done +else + [ -f "$CONTAINERFILE" ] || die 3 "Containerfile '$CONTAINERFILE' not found" + debug "Using containerfile %s\n" "$CONTAINERFILE" + containerfile=$CONTAINERFILE +fi + +[ -f "$containerfile" ] || die 4 "No containerfile found" + +[ -d "$BUILD_CONTEXT" ] || die 5 "Build context '$BUILD_CONTEXT' not found" + +debug 'Building image from %s in in %s\n' "$containerfile" "$here" +# Build the image +if command -v podman 2>/dev/null +then + runtime=podman +elif command -v docker 2>/dev/null +then + runtime=docker +else + die 6 "No container runtime found" +fi + +revision=$(git rev-parse HEAD) +shortref=$(git rev-parse --short "$revision") +repo_url=$(git remote get-url origin) +if [ -z "$repo_url" ] +then + die 7 "No remote found" +fi +if [[ $repo_url == *github.com/* ]] +then + owner_and_repo=${repo_url#*github.com/} +else + owner_and_repo=${repo_url##*:} +fi +# Get rid of the trailing .git +service=$(basename "$owner_and_repo" .git) +owner=$(dirname "$owner_and_repo") + +full_tag=$IMAGE_NAME:$tag +# Pass any extra arguments to the build command ("$@" contains the rest of the arguments) +$runtime build --tag "$full_tag" "$@" \ + --label org.opencontainers.image.created="$(date --utc --iso-8601=seconds)" \ + --label org.opencontainers.image.description="Image for $service" \ + --label org.opencontainers.image.licenses="$LICENSE" \ + --label org.opencontainers.image.revision="$revision" \ + --label org.opencontainers.image.url="$repo_url" \ + --label org.opencontainers.image.title="$IMAGE_NAME" \ + --label org.opencontainers.image.source="Generated by ruby-automation's build_image.sh ($USER@$HOSTNAME)" \ + --label org.opencontainers.image.version="$full_tag" \ + --label shortref="$shortref" \ + --build-arg UBUNTU_VERSION="$UBUNTU_VERSION" \ + --build-arg RUBY_VERSION="$RUBY_VERSION" \ + -f "$containerfile" "$BUILD_CONTEXT" || die 8 "Failed to build image" + +[ $push -eq 1 ] || exit 0 +if ! $runtime login --get-login "$REGISTRY" >/dev/null 2>/dev/null +then + printf "Not logged in to '%s', trying to login\n" "$REGISTRY" >&2 + [ -z "$REGISTRY_TOKEN" ] && die 9 "No REGISTRY_TOKEN (nor GITHUB_TOKEN) set, cannot login" + printf "%s" "$REGISTRY_TOKEN" | $runtime login -u "$REGISTRY_TOKEN" --password-stdin "$REGISTRY" || die 10 "Failed to login to $REGISTRY" +fi + +# Split 1.2.3 into 1.2.3, 1.2, 1. We want to tag our image with all 3 of these +mapfile -t tags < <(echo "$tag" | awk -F'.' 'NF==3{print; print $1"."$2; print $1; next} NF==2{print; print $1; next} {print}') +for t in "${tags[@]}" +do + new_tag=$IMAGE_NAME:$t + registry_image_name="$REGISTRY/$owner/$new_tag" + if [ "$runtime" = "podman" ] + then + if [ "$full_tag" != "$new_tag" ] + then + debug "Tagging %s as %s\n" "$full_tag" "$new_tag" + podman tag "$full_tag" "$new_tag" || die 11 "Failed to tag image $full_tag as $new_tag" + fi + podman push "$new_tag" "$registry_image_name" || die 12 "Failed to push image $new_tag to $registry_image_name" + else + debug "Tagging %s as %s\n" "$full_tag" "$registry_image_name" + docker tag "$full_tag" "$registry_image_name" || die 13 "Failed to tag image $full_tag as $registry_image_name" + docker push "$registry_image_name" || die 14 "Failed to push image $new_tag to $registry_image_name" + fi +done + +# vim: set foldmethod=marker et ts=4 sts=4 sw=4 ft=bash : diff --git a/ci/publish-gem.sh b/ci/publish-gem.sh new file mode 100755 index 0000000..d25682c --- /dev/null +++ b/ci/publish-gem.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +if readlink -f . >/dev/null 2>&1 # {{{ makes readlink work on mac +then + readlink=readlink +else + if greadlink -f . >/dev/null 2>&1 + then + readlink=greadlink + else + printf "You must install greadlink to use this (brew install coreutils)\n" >&2 + fi +fi # }}} + +# Set here to the full path to this script +me=${BASH_SOURCE[0]} +[ -L "$me" ] && me=$($readlink -f "$me") +here=$(cd "$(dirname "$me")" && pwd) +just_me=$(basename "$me") + +: "${GEM_NAME:=sequel-pgt_outbox}" +: "${GIT_ORG:=rubyists}" + +GEM_HOST=$1 +: "${GEM_HOST:=rubygems}" + +case "$GEM_HOST" in + rubygems) + gem_key='rubygems' + gem_host='https://rubygems.org' + ;; + github) + gem_key='github' + gem_host="https://rubygems.pkg.github.com/$GIT_ORG" + # Replace the gem host in the gemspec, so it allows pushing to the GitHub package registry + sed --in-place=.bak -e "s|https://rubygems.org|https://rubygems.pkg.github.com/$GIT_ORG|" "$here/../$GEM_NAME".gemspec + # Restore the original gemspec after the script finishes + trap 'mv -v "$here/../$GEM_NAME".gemspec.bak "$here/../$GEM_NAME".gemspec' EXIT + ;; + *) + printf 'Unknown GEM_HOST: %s\n' "$GEM_HOST" >&2 + exit 1 + ;; +esac + +# We only want this part running in CI, with no ~/.gem dir +# For local testing, you should have a ~/.gem/credentials file with +# the keys you need to push to rubygems or github +if [ ! -d ~/.gem ] +then + if [ -z "$GEM_TOKEN" ] + then + printf 'No GEM_TOKEN provided, cannot publish\n' >&2 + exit 1 + fi + mkdir -p ~/.gem + printf '%s\n:%s: %s\n' '---' "$gem_key" "$GEM_TOKEN" > ~/.gem/credentials + chmod 600 ~/.gem/credentials +fi + +if [ -f "$here"/../.version.txt ] +then + version=$(<"$here"/../.version.txt) +else + version=$(git describe --tags --abbrev=0 | sed -e 's/^v//') +fi + +gem="$(printf '%s-%s.gem' "$GEM_NAME" "$version")" +if [[ "${TRACE:-false}" == true || "${ACTIONS_STEP_DEBUG:-false}" == true ]] +then + printf "DEBUG: [%s] Building And Publishing %s to %s\n" "$just_me" "$gem" "$gem_host" >&2 +fi + +bundle exec gem build +bundle exec gem push -k "$gem_key" --host "$gem_host" "$gem" + +# vim: set foldmethod=marker et ts=4 sts=4 sw=4 ft=bash : diff --git a/leopard.gemspec b/leopard.gemspec index 5fda928..4205f41 100644 --- a/leopard.gemspec +++ b/leopard.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |spec| spec.email = ['bougyman@users.noreply.github.com'] spec.summary = 'A server to supervise concurrent NATS ServiceApi workers.' - spec.description = 'Leopard is a puma-like server for managing concurrent NATS ServiceApi endpoint workers' # rubocop:disable Layout/LineLength + spec.description = 'Leopard is a puma-like server for managing concurrent NATS ServiceApi endpoint workers' spec.homepage = 'https://github.com/rubyists/leopard' spec.license = 'MIT' spec.required_ruby_version = '>= 3.3.0' diff --git a/lib/leopard/version.rb b/lib/leopard/version.rb new file mode 100644 index 0000000..be1c23a --- /dev/null +++ b/lib/leopard/version.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Rubyists + module Leopard + # x-release-please-start-version + VERSION = '0.1.0' + # x-release-please-end + end +end diff --git a/test/leopard/test_leopard.rb b/test/leopard/test_leopard.rb new file mode 100755 index 0000000..2d8cc9d --- /dev/null +++ b/test/leopard/test_leopard.rb @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require_relative '../test_helper' diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 0000000..0320dd5 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) + +if (coverage = ENV.delete('COVERAGE')) + require 'simplecov' + + SimpleCov.start do + enable_coverage :branch + command_name coverage + add_filter '/test/' + add_group('Missing') { |src| src.covered_percent < 100 } + add_group('Covered') { |src| src.covered_percent == 100 } + end +end + +ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins +gem 'minitest' +require 'minitest/global_expectations/autorun'