Skip to content
Merged
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
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git
.gitignore
.docker-cache
.bundle
coverage
pkg
node_modules
vendor/bundle
.env
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.jpg binary

25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,28 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/coverage.json
fail_ci_if_error: true
e2e:
needs: ci
if: >
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
env:
TRANSLOADIT_KEY: ${{ secrets.TRANSLOADIT_KEY }}
TRANSLOADIT_SECRET: ${{ secrets.TRANSLOADIT_SECRET }}
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- name: Ensure e2e credentials are configured
if: ${{ env.TRANSLOADIT_KEY == '' || env.TRANSLOADIT_SECRET == '' }}
run: |
echo "TRANSLOADIT_KEY and TRANSLOADIT_SECRET must be configured in repository secrets to run the e2e job." >&2
exit 1
- name: Run end-to-end upload test
env:
RUBY_SDK_E2E: 1
if: ${{ env.TRANSLOADIT_KEY != '' && env.TRANSLOADIT_SECRET != '' }}
run: bundle exec ruby -Itest test/integration/test_e2e_upload.rb
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ transloadit-*.gem
env.sh
.env
vendor/bundle/
.docker-cache/
.cache/rubocop_cache/04e06e0faf5ad652d8bcbcfd85bac5f6c32e711e/3031a80880d8a984708138f0d003f77c4bad2648
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### 3.1.1 / 2025-10-28

- Add optional live end-to-end upload harness and CI job for parity verification, defaulted in Docker tests (kvz)
- Restore missing `require "uri"` to prevent `NameError` when loading `Transloadit::Request` (kvz)

### 3.1.0 / 2024-11-24

- Add Smart CDN signature support via `signed_smart_cdn_url` method (kvz)
Expand Down
95 changes: 95 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Contributing

Thanks for helping improve the Transloadit Ruby SDK! This guide covers local development, testing, and publishing new releases.

## Local Development

After cloning the repository, install dependencies and run the test suite:

```bash
bundle install
bundle exec rake test
```

To exercise the signature parity suite against the Node.js CLI, make sure `npx transloadit` is available and run:

```bash
TEST_NODE_PARITY=1 bundle exec rake test
```

You can warm the CLI cache ahead of time:

```bash
TRANSLOADIT_KEY=... TRANSLOADIT_SECRET=... \
npx --yes transloadit smart_sig --help
TRANSLOADIT_KEY=... TRANSLOADIT_SECRET=... \
npx --yes transloadit sig --algorithm sha384 --help
```

Set `COVERAGE=0` to skip coverage instrumentation if desired:

```bash
COVERAGE=0 bundle exec rake test
```

## Docker Workflow

The repository ships with a helper that runs tests inside a reproducible Docker image:

```bash
./scripts/test-in-docker.sh
```

Pass a custom command to run alternatives (Bundler still installs first):

```bash
./scripts/test-in-docker.sh bundle exec ruby -Itest test/unit/transloadit/test_request.rb
```

The script forwards environment variables such as `TEST_NODE_PARITY` and credentials from `.env`, so you can combine parity checks and integration tests. End-to-end uploads are enabled by default; unset them by running:

```bash
RUBY_SDK_E2E=0 ./scripts/test-in-docker.sh
```

## Live End-to-End Test

To exercise the optional live upload:

```bash
RUBY_SDK_E2E=1 TRANSLOADIT_KEY=... TRANSLOADIT_SECRET=... \
./scripts/test-in-docker.sh bundle exec ruby -Itest test/integration/test_e2e_upload.rb
```

The test uploads `chameleon.jpg`, resizes it, and asserts on a real assembly response.

## Releasing to RubyGems

1. Update the version and changelog:
- Bump `lib/transloadit/version.rb`.
- Add a corresponding entry to `CHANGELOG.md`.
2. Run the full test suite (including Docker, parity, and e2e checks as needed).
3. Commit the release changes and tag:
```bash
git commit -am "Release X.Y.Z"
git tag -a vX.Y.Z -m "Release X.Y.Z"
```
4. Push the commit and tag:
```bash
git push origin main
git push origin vX.Y.Z
```
5. Publish the gem using the helper script:
```bash
GEM_HOST_API_KEY=... ./scripts/notify-registry.sh
```
6. Draft a GitHub release from the new tag and publish the generated notes.

### RubyGems Credentials

- You must belong to the `transloadit` organization on RubyGems with permission to push the `transloadit` gem.
- Generate an API key with **Push Rubygems** permissions at <https://rubygems.org/profile/edit>. Copy the token and keep it secure.
- Export the token as `GEM_HOST_API_KEY` in your environment before running `./scripts/notify-registry.sh`. The script refuses to run if the variable is missing.

That’s it! Thank you for contributing.

19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# syntax=docker/dockerfile:1

FROM ruby:3.3 AS base

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
git \
curl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# Install Node.js for parity checks
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& npm install -g npm@latest \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /workspace
32 changes: 1 addition & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,34 +467,4 @@ If you still need support for Ruby 2.x, 2.0.1 is the last version that supports

## Contributing

Contributions are welcome!

### Running tests

```bash
bundle install
bundle exec rake test
```

To also test parity against the Node.js reference implementation, run:

```bash
TEST_NODE_PARITY=1 bundle exec rake test
```

To disable coverage reporting, run:

```bash
COVERAGE=0 bundle exec rake test
```

### Releasing on RubyGems

Let's say you wanted to release version `3.1.0`, here are the steps:

1. Update the version number in the version file `version.rb` and `CHANGELOG.md`
2. Commit: `git add CHANGELOG.md lib/transloadit/version.rb && git commit -m "Release 3.1.0"`
3. Create a git tag: `git tag -a v3.1.0 -m "Release 3.1.0"`
4. Push the git tag: `git push origin v3.1.0`
5. Release on RubyGems: `gem build transloadit.gemspec && gem push transloadit-3.1.0.gem`
6. Draft a release [here](https://github.com/transloadit/ruby-sdk/releases). Click the `v3.1.0` tag and click `Generate release notes`. Inspect and Publish.
See [CONTRIBUTING.md](CONTRIBUTING.md) for local development, testing, and release instructions.
Binary file added chameleon.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion lib/transloadit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
require "date"
require "json"
require "openssl"
require "uri"
require "cgi"
require "uri"

#
# Implements the Transloadit REST API in Ruby. Check the {file:README.md README}
Expand Down
1 change: 1 addition & 0 deletions lib/transloadit/response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def inspect
#
def extend!(mod)
extend(mod)

self
end

Expand Down
2 changes: 1 addition & 1 deletion lib/transloadit/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
class Transloadit
VERSION = "3.1.0"
VERSION = "3.1.1"
end
57 changes: 57 additions & 0 deletions scripts/notify-registry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash
set -euo pipefail

IMAGE_NAME=${IMAGE_NAME:-transloadit-ruby-sdk-dev}

err() {
echo "notify-registry: $*" >&2
}

if ! command -v docker >/dev/null 2>&1; then
err "Docker is required to publish the gem."
exit 1
fi

if [[ -z "${GEM_HOST_API_KEY:-}" ]]; then
err "GEM_HOST_API_KEY environment variable is not set. Generate a RubyGems API key with push permissions and export it before running this script."
exit 1
fi

if ! docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
err "Docker image '$IMAGE_NAME' not found. Building it now..."
docker build -t "$IMAGE_NAME" -f Dockerfile .
fi

version=$(
docker run --rm \
-v "$PWD":/workspace \
-w /workspace \
"$IMAGE_NAME" \
ruby -Ilib -e 'require "transloadit/version"; puts Transloadit::VERSION'
)

gem_file="transloadit-${version}.gem"

err "Building ${gem_file}..."
docker run --rm \
--user "$(id -u):$(id -g)" \
-e HOME=/workspace \
-v "$PWD":/workspace \
-w /workspace \
"$IMAGE_NAME" \
bash -lc "set -euo pipefail; rm -f ${gem_file}; gem build transloadit.gemspec >/dev/null"

err "Pushing ${gem_file} to RubyGems..."
docker run --rm \
--user "$(id -u):$(id -g)" \
-e HOME=/workspace \
-e GEM_HOST_API_KEY="$GEM_HOST_API_KEY" \
-v "$PWD":/workspace \
-w /workspace \
"$IMAGE_NAME" \
bash -lc "set -euo pipefail; gem push ${gem_file}"

err "Removing local ${gem_file}..."
rm -f "${gem_file}"

echo "notify-registry: Successfully pushed ${gem_file} to RubyGems."
89 changes: 89 additions & 0 deletions scripts/test-in-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env bash
set -euo pipefail

IMAGE_NAME=${IMAGE_NAME:-transloadit-ruby-sdk-dev}
CACHE_DIR=.docker-cache

ensure_docker() {
if ! command -v docker >/dev/null 2>&1; then
echo "Docker is required to run this script." >&2
exit 1
fi

if ! docker info >/dev/null 2>&1; then
if [[ -z "${DOCKER_HOST:-}" && -S "$HOME/.colima/default/docker.sock" ]]; then
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
fi
fi

if ! docker info >/dev/null 2>&1; then
echo "Docker daemon is not reachable. Start Docker (or Colima) and retry." >&2
exit 1
fi
}

configure_platform() {
if [[ -z "${DOCKER_PLATFORM:-}" ]]; then
local arch
arch=$(uname -m)
if [[ "$arch" == "arm64" || "$arch" == "aarch64" ]]; then
DOCKER_PLATFORM=linux/amd64
fi
fi
}

ensure_docker
configure_platform

if [[ $# -eq 0 ]]; then
RUN_CMD='set -e; bundle install --jobs 4 --retry 3; bundle exec rake test'
else
printf -v USER_CMD '%q ' "$@"
RUN_CMD="set -e; bundle install --jobs 4 --retry 3; ${USER_CMD}"
fi

mkdir -p "$CACHE_DIR/bundle" "$CACHE_DIR/npm-cache"

BUILD_ARGS=()
if [[ -n "${DOCKER_PLATFORM:-}" ]]; then
BUILD_ARGS+=(--platform "$DOCKER_PLATFORM")
fi
BUILD_ARGS+=(-t "$IMAGE_NAME" -f Dockerfile .)

docker build "${BUILD_ARGS[@]}"

DOCKER_ARGS=(
--rm
--user "$(id -u):$(id -g)"
-e HOME=/workspace
-e BUNDLE_PATH=/workspace/$CACHE_DIR/bundle
-e BUNDLE_APP_CONFIG=/workspace/$CACHE_DIR/bundle-config
-e BUNDLE_CACHE_PATH=/workspace/$CACHE_DIR/bundle-cache
-e npm_config_cache=/workspace/$CACHE_DIR/npm-cache
-e TEST_NODE_PARITY="${TEST_NODE_PARITY:-0}"
-e RUBY_SDK_E2E="${RUBY_SDK_E2E:-1}"
-v "$PWD":/workspace
-w /workspace
)

if [[ -n "${DOCKER_PLATFORM:-}" ]]; then
DOCKER_ARGS+=(--platform "$DOCKER_PLATFORM")
fi

if [[ -f .env ]]; then
DOCKER_ARGS+=(--env-file "$PWD/.env")
fi

PASSTHROUGH_ENV_VARS=(
TRANSLOADIT_KEY
TRANSLOADIT_SECRET
TRANSLOADIT_TEMPLATE_ID
)

for var in "${PASSTHROUGH_ENV_VARS[@]}"; do
if [[ -n "${!var:-}" ]]; then
DOCKER_ARGS+=(-e "$var=${!var}")
fi
done

exec docker run "${DOCKER_ARGS[@]}" "$IMAGE_NAME" bash -lc "$RUN_CMD"
Loading