Skip to content

Commit 1593669

Browse files
committed
first commit
0 parents  commit 1593669

File tree

31 files changed

+873
-0
lines changed

31 files changed

+873
-0
lines changed

.github/workflows/release.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- v*
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
release:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- name: Set up Ruby
18+
uses: ruby/setup-ruby@v1
19+
with:
20+
ruby-version: '3.4'
21+
bundler-cache: true
22+
- name: Build gem
23+
run: |
24+
gem build *.gemspec
25+
- name: Publish to RubyGems
26+
uses: cadwallion/publish-rubygems-action@master
27+
env:
28+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}

.github/workflows/test.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Test
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: [ main, master ]
7+
pull_request:
8+
branches: [ main, master ]
9+
schedule:
10+
- cron: "0 0 * * 0"
11+
12+
permissions:
13+
contents: read
14+
15+
concurrency:
16+
group: test-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
test:
21+
strategy:
22+
matrix:
23+
ruby: ["3.2", "3.3", "3.4"]
24+
activemodel: ["~> 7.2", "~> 8.0"]
25+
runs-on: ubuntu-latest
26+
27+
steps:
28+
- uses: actions/checkout@v4
29+
- name: Set up Environment Variables
30+
run: |
31+
echo "ACTIVEMODEL_VERSION=${{ matrix.activemodel }}" >> $GITHUB_ENV
32+
33+
- name: Set up Ruby
34+
uses: ruby/setup-ruby@v1
35+
with:
36+
ruby-version: ${{ matrix.ruby }}
37+
bundler-cache: false
38+
- name: Prepare Gemfile for matrix
39+
run: |
40+
bundle config set frozen false
41+
bundle lock --add-platform ruby --add-platform x86_64-linux || true
42+
if [ -n "${{ matrix.activemodel }}" ]; then
43+
bundle lock --update activemodel || true
44+
fi
45+
- name: Install dependencies
46+
run: bundle install --jobs 4 --retry 1
47+
48+
- name: Run tests
49+
run: bundle exec rake test
50+
51+
ar_integration:
52+
strategy:
53+
matrix:
54+
ruby: ["3.2", "3.3", "3.4"]
55+
activerecord: ["~> 7.2", "~> 8.0"]
56+
runs-on: ubuntu-latest
57+
58+
steps:
59+
- uses: actions/checkout@v4
60+
- name: Set up Environment Variables
61+
run: |
62+
echo "AR_INTEGRATION=1" >> $GITHUB_ENV
63+
echo "ACTIVERECORD_VERSION=${{ matrix.activerecord }}" >> $GITHUB_ENV
64+
- name: Set up Ruby
65+
uses: ruby/setup-ruby@v1
66+
with:
67+
ruby-version: ${{ matrix.ruby }}
68+
bundler-cache: false
69+
- name: Prepare Gemfile for AR matrix
70+
run: |
71+
bundle config set frozen false
72+
bundle lock --add-platform ruby --add-platform x86_64-linux || true
73+
bundle lock --update activerecord sqlite3 || true
74+
- name: Install dependencies
75+
run: bundle install --jobs 4 --retry 1
76+
- name: Run integration tests
77+
run: bundle exec rake test

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/.bundle/
2+
/.yardoc
3+
/_yardoc/
4+
/coverage/
5+
/doc/
6+
/pkg/
7+
/spec/reports/
8+
/tmp/
9+
10+
/vendor/

.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.4.3

.travis.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
sudo: false
3+
language: ruby
4+
cache: bundler
5+
rvm:
6+
- 2.6.10
7+
before_install: gem install bundler -v 1.17.2

Gemfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
source "https://rubygems.org"
2+
3+
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4+
5+
# Allow CI to pin a specific ActiveModel version via env var
6+
am_ver = ENV["ACTIVEMODEL_VERSION"]
7+
gem "activemodel", am_ver if am_ver
8+
9+
# Optional: ActiveRecord integration testing
10+
if ENV["AR_INTEGRATION"] == "1"
11+
ar_ver = ENV["ACTIVERECORD_VERSION"]
12+
gem "activerecord", ar_ver || ">= 7.0", "< 9"
13+
sqlite_req = (ar_ver && ar_ver.start_with?("~> 8")) ? ">= 2.1" : ">= 1.6"
14+
gem "sqlite3", sqlite_req
15+
end
16+
17+
# Specify your gem's dependencies in activerecord-s3-bucket-name-validator.gemspec
18+
gemspec

Gemfile.lock

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
PATH
2+
remote: .
3+
specs:
4+
activerecord-s3-bucket-name-validator (0.1.0)
5+
activemodel (>= 7.0, < 9)
6+
i18n (>= 1.0)
7+
8+
GEM
9+
remote: https://rubygems.org/
10+
specs:
11+
activemodel (8.0.3)
12+
activesupport (= 8.0.3)
13+
activesupport (8.0.3)
14+
base64
15+
benchmark (>= 0.3)
16+
bigdecimal
17+
concurrent-ruby (~> 1.0, >= 1.3.1)
18+
connection_pool (>= 2.2.5)
19+
drb
20+
i18n (>= 1.6, < 2)
21+
logger (>= 1.4.2)
22+
minitest (>= 5.1)
23+
securerandom (>= 0.3)
24+
tzinfo (~> 2.0, >= 2.0.5)
25+
uri (>= 0.13.1)
26+
base64 (0.3.0)
27+
benchmark (0.4.1)
28+
bigdecimal (3.2.3)
29+
concurrent-ruby (1.3.5)
30+
connection_pool (2.5.4)
31+
drb (2.2.3)
32+
i18n (1.14.7)
33+
concurrent-ruby (~> 1.0)
34+
logger (1.7.0)
35+
minitest (5.25.5)
36+
rake (13.3.0)
37+
securerandom (0.4.1)
38+
tzinfo (2.0.6)
39+
concurrent-ruby (~> 1.0)
40+
uri (1.0.3)
41+
42+
PLATFORMS
43+
arm64-darwin-24
44+
ruby
45+
46+
DEPENDENCIES
47+
activerecord-s3-bucket-name-validator!
48+
bundler (>= 1.17)
49+
minitest (>= 5.0)
50+
rake (>= 10.0)
51+
52+
BUNDLED WITH
53+
2.6.7

LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2025 Claudio Poli
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# ActiveModel S3 Bucket Name Validator
2+
3+
ActiveModel validator for Amazon S3 bucket names. It implements the official AWS naming rules for:
4+
- General purpose buckets (classic S3)
5+
- Directory buckets (S3 Express One Zone)
6+
- S3 Tables buckets
7+
8+
Works in any class using ActiveModel::Validations and in Rails/ActiveRecord models. Ships with i18n messages in multiple locales.
9+
10+
## Installation
11+
12+
Add to your Gemfile:
13+
14+
```ruby
15+
gem "activerecord-s3-bucket-name-validator"
16+
```
17+
18+
Then bundle:
19+
20+
```bash
21+
bundle install
22+
```
23+
24+
## Compatibility
25+
26+
- Ruby: 3.1, 3.2, 3.3, 3.4 (CI runs 3.2–3.4)
27+
- ActiveModel: 7.2, 8.0 (CI targets)
28+
- Rails/ActiveRecord: supported via ActiveModel::Validations (no Rails runtime dependency)
29+
30+
## Quickstart
31+
32+
Plain ActiveModel:
33+
34+
```ruby
35+
class StorageConfig
36+
include ActiveModel::Model
37+
attr_accessor :bucket_name
38+
validates :bucket_name, s3_bucket_name: true
39+
end
40+
```
41+
42+
ActiveRecord model:
43+
44+
```ruby
45+
class Storage < ApplicationRecord
46+
validates :bucket_name, s3_bucket_name: true
47+
end
48+
```
49+
50+
## Options
51+
52+
- `type``:general_purpose` (default), `:directory`, or `:table`
53+
- `transfer_acceleration` — when `true`, periods are forbidden for general-purpose buckets
54+
55+
Examples:
56+
57+
```ruby
58+
validates :bucket_name, s3_bucket_name: { transfer_acceleration: true }
59+
validates :bucket_name, s3_bucket_name: { type: :directory }
60+
validates :bucket_name, s3_bucket_name: { type: :table }
61+
```
62+
63+
## i18n
64+
65+
Error keys provided:
66+
- `activemodel.errors.messages.s3_bucket_name_invalid_general`
67+
- `activemodel.errors.messages.s3_bucket_name_invalid_transfer_acceleration`
68+
- `activemodel.errors.messages.s3_bucket_name_invalid_directory`
69+
- `activemodel.errors.messages.s3_bucket_name_invalid_table`
70+
71+
Locales shipped: en, es, it, fr, de, pt-BR, ja, ko, zh-CN, zh-TW, ru, nl.
72+
73+
Rails loads locales via a Railtie; plain ActiveModel loads them at require-time. Override by adding your own YAML with the same keys.
74+
75+
## What’s validated (high level)
76+
77+
- Length 3–63, allowed characters, begin/end alphanumeric
78+
- No adjacent periods; not IP-like (general purpose)
79+
- Reserved prefixes/suffixes per AWS docs (for example `xn--`, `sthree-`, `amzn-s3-demo-`, `-s3alias`, `--ol-s3`, `.mrap`, `--x-s3`, `--table-s3`)
80+
- Directory buckets must end with `--<zone-id>--x-s3`
81+
- S3 Tables buckets disallow periods and underscores
82+
- Optional TA mode forbids periods
83+
84+
Note: Global/partition uniqueness and immutability are service-side constraints and not enforced locally.
85+
86+
## Examples
87+
88+
Valid (general purpose):
89+
90+
```text
91+
my-example-bucket
92+
example.com
93+
```
94+
95+
Invalid (general purpose):
96+
97+
```text
98+
ex..ample
99+
192.168.5.4
100+
xn--abc
101+
foo--x-s3
102+
```
103+
104+
## Running tests (for contributors)
105+
106+
```bash
107+
# ActiveModel-only
108+
bundle install
109+
bundle exec rake test
110+
111+
# With ActiveRecord integration (in-memory sqlite)
112+
AR_INTEGRATION=1 ACTIVERECORD_VERSION="~> 8.0" bundle install
113+
AR_INTEGRATION=1 ACTIVERECORD_VERSION="~> 8.0" bundle exec rake test
114+
```
115+
116+
## License
117+
118+
MIT — see `LICENSE.txt`.

Rakefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
require "bundler/gem_tasks"
2+
require "rake/testtask"
3+
4+
Rake::TestTask.new(:test) do |t|
5+
t.libs << "test"
6+
t.libs << "lib"
7+
t.test_files = FileList["test/**/*_test.rb"]
8+
end
9+
10+
task :default => :test

0 commit comments

Comments
 (0)