diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cab9e8..defc794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,24 +17,17 @@ jobs: strategy: fail-fast: false matrix: - RUBY_VERSION: [2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 3.3, 3.4] + RUBY_VERSION: [2.3, 2.4, 2.5, 2.6, 2.7, 3.1, 3.2, 3.3, 3.4] + env: + RUBY_VERSION: ${{ matrix.RUBY_VERSION }} steps: - name: Check out code uses: actions/checkout@v4 with: persist-credentials: false - - name: Install Ruby - uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 # v1.267.0 - with: - ruby-version: ${{ matrix.RUBY_VERSION }} - bundler: 1.17.3 - - - name: Bundle install - run: bundle install - - name: Rubocop - run: bundle exec rake rubocop + run: make lint - name: Rspec - run: bundle exec rspec + run: make test diff --git a/.gitignore b/.gitignore index d87d4be..12a45db 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ spec/reports test/tmp test/version_tmp tmp +/docker/ruby-*/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2be7314 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +ARG RUBY_VERSION=2.3.1 +FROM ruby:${RUBY_VERSION} + +ARG BUNDLER_VERSION=1.17.3 +ENV BUNDLER_VERSION=${BUNDLER_VERSION} +RUN if [ "${BUNDLER_VERSION}" != "" ] ; then \ + gem install bundler -v "${BUNDLER_VERSION}" ; \ + fi + +WORKDIR /app +COPY Gemfile /app/ +COPY aptible-api.gemspec /app/ +RUN mkdir -p /app/lib/aptible/api/ +COPY lib/aptible/api/version.rb /app/lib/aptible/api/ + +RUN bundle install + +COPY . /app + +CMD ["bash"] diff --git a/Gemfile b/Gemfile index 444c64e..ba51241 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,8 @@ source 'https://rubygems.org' # ActiveSupport version depends on Ruby version for compatibility -if RUBY_VERSION < '3.0' +# ActiveSupport 4.x is incompatible with Ruby 2.7+ (BigDecimal.new removed) +if RUBY_VERSION < '2.7' gem 'activesupport', '~> 4.0' else gem 'activesupport', '>= 5.2' diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..09eccf4 --- /dev/null +++ b/Makefile @@ -0,0 +1,68 @@ + +export COMPOSE_IGNORE_ORPHANS ?= true +export RUBY_VERSION ?= 2.3.1 +RUBY_VERSION_MAJOR = $(word 1,$(subst ., ,$(RUBY_VERSION))) +export BUNDLER_VERSION ?= +ifeq ($(BUNDLER_VERSION),) +ifeq ($(RUBY_VERSION_MAJOR),2) +export BUNDLER_VERSION = 1.17.3 +endif +endif +PROJECT_NAME = $(shell ls *.gemspec | sed 's/\.gemspec//') +export COMPOSE_PROJECT_NAME ?= $(PROJECT_NAME)-$(subst .,_,$(RUBY_VERSION)) + +default: help + +## Show this help message +help: + @echo "\n\033[1;34mAvailable targets:\033[0m\n" + @awk 'BEGIN {FS = ":"; prev = ""} \ + /^## / {prev = substr($$0, 4); next} \ + /^[a-zA-Z_-]+:/ {if (prev != "") printf " \033[1;36m%-20s\033[0m %s\n", $$1, prev; prev = ""} \ + {prev = ""}' $(MAKEFILE_LIST) | sort + @echo + +BUILD_ARGS ?= +## Build and pull docker compose images +build: gemfile-lock + docker compose build --pull $(BUILD_ARGS) + +## Create a Gemfile.lock specific to the container (i.e., for the ruby version) +gemfile-lock: + mkdir -pv ./docker/ruby-$(RUBY_VERSION)/ && \ + echo '' > ./docker/ruby-$(RUBY_VERSION)/Gemfile.lock + +## Open shell in a docker container, supports CMD= +bash: build + $(MAKE) run CMD=bash + +CMD ?= bash +## Run command in a docker container, supports CMD= +run: + docker compose run --rm runner $(CMD) + +## Run tests in a docker container, supports ARGS= +test: build + $(MAKE) test-direct ARGS="$(ARGS)" + +## Run tests in a docker container without building, supports ARGS= +test-direct: + $(MAKE) run CMD="bundle exec rspec $(ARGS)" + +## Run rubocop in a docker container, supports ARGS= +lint: build + $(MAKE) lint-direct ARGS="$(ARGS)" + +## Run rubocop in a docker container without building, supports ARGS= +lint-direct: + $(MAKE) run CMD="bundle exec rake rubocop $(ARGS)" + +## Clean up docker compose resources +clean: clean-gemfile-lock + docker compose down --remove-orphans --volumes + +## Clean up the container specific Gemfile.lock +clean-gemfile-lock: + rm -v ./docker/ruby-$(RUBY_VERSION)/Gemfile.lock ||: + +.PHONY: build bash test diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..358f47e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + runner: + build: + context: . + args: + RUBY_VERSION: ${RUBY_VERSION:-2.3.1} + BUNDLER_VERSION: ${BUNDLER_VERSION:-} + volumes: + - type: bind + source: . + target: /app + - ./docker/ruby-${RUBY_VERSION}/Gemfile.lock:/app/Gemfile.lock