attio 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.codecov.yml +52 -0
  3. data/.github/CODEOWNERS +28 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +28 -0
  6. data/.github/dependabot.yml +54 -0
  7. data/.github/pull_request_template.md +40 -0
  8. data/.github/workflows/ci.yml +112 -0
  9. data/.github/workflows/dependabot-auto-merge.yml +45 -0
  10. data/.github/workflows/pr_checks.yml +145 -0
  11. data/.github/workflows/release.yml +147 -0
  12. data/.gitignore +10 -0
  13. data/.rspec +4 -0
  14. data/.rubocop.yml +133 -0
  15. data/.yardopts +18 -0
  16. data/CHANGELOG.md +34 -0
  17. data/CODE_OF_CONDUCT.md +37 -0
  18. data/CONTRIBUTING.md +280 -0
  19. data/Gemfile +17 -0
  20. data/Gemfile.lock +127 -0
  21. data/LICENSE.txt +21 -0
  22. data/README.md +292 -0
  23. data/Rakefile +57 -0
  24. data/SECURITY.md +59 -0
  25. data/attio.gemspec +34 -0
  26. data/bin/console +14 -0
  27. data/bin/setup +8 -0
  28. data/danger/Dangerfile +121 -0
  29. data/docs/.nojekyll +0 -0
  30. data/docs/Attio/AuthenticationError.html +152 -0
  31. data/docs/Attio/Client.html +1373 -0
  32. data/docs/Attio/ConnectionPool/TimeoutError.html +148 -0
  33. data/docs/Attio/ConnectionPool.html +944 -0
  34. data/docs/Attio/Error.html +152 -0
  35. data/docs/Attio/HttpClient/ConnectionError.html +152 -0
  36. data/docs/Attio/HttpClient/TimeoutError.html +152 -0
  37. data/docs/Attio/HttpClient.html +1329 -0
  38. data/docs/Attio/Logger.html +747 -0
  39. data/docs/Attio/NotFoundError.html +152 -0
  40. data/docs/Attio/RateLimitError.html +152 -0
  41. data/docs/Attio/RequestLogger.html +780 -0
  42. data/docs/Attio/Resources/Attributes.html +508 -0
  43. data/docs/Attio/Resources/Base.html +624 -0
  44. data/docs/Attio/Resources/Lists.html +1002 -0
  45. data/docs/Attio/Resources/Objects.html +415 -0
  46. data/docs/Attio/Resources/Records.html +1465 -0
  47. data/docs/Attio/Resources/Users.html +415 -0
  48. data/docs/Attio/Resources/Workspaces.html +324 -0
  49. data/docs/Attio/Resources.html +141 -0
  50. data/docs/Attio/RetryHandler.html +1023 -0
  51. data/docs/Attio/ServerError.html +152 -0
  52. data/docs/Attio/ValidationError.html +152 -0
  53. data/docs/Attio.html +397 -0
  54. data/docs/SETUP.md +117 -0
  55. data/docs/_index.html +378 -0
  56. data/docs/class_list.html +54 -0
  57. data/docs/css/common.css +1 -0
  58. data/docs/css/full_list.css +58 -0
  59. data/docs/css/style.css +503 -0
  60. data/docs/example.rb +119 -0
  61. data/docs/file.CHANGELOG.html +124 -0
  62. data/docs/file.README.html +371 -0
  63. data/docs/file_list.html +64 -0
  64. data/docs/frames.html +22 -0
  65. data/docs/index.html +371 -0
  66. data/docs/js/app.js +344 -0
  67. data/docs/js/full_list.js +242 -0
  68. data/docs/js/jquery.js +4 -0
  69. data/docs/method_list.html +750 -0
  70. data/docs/top-level-namespace.html +110 -0
  71. data/lib/attio/client.rb +118 -0
  72. data/lib/attio/connection_pool.rb +69 -0
  73. data/lib/attio/errors.rb +9 -0
  74. data/lib/attio/http_client.rb +100 -0
  75. data/lib/attio/logger.rb +110 -0
  76. data/lib/attio/resources/attributes.rb +26 -0
  77. data/lib/attio/resources/base.rb +55 -0
  78. data/lib/attio/resources/lists.rb +56 -0
  79. data/lib/attio/resources/objects.rb +20 -0
  80. data/lib/attio/resources/records.rb +158 -0
  81. data/lib/attio/resources/users.rb +20 -0
  82. data/lib/attio/resources/workspaces.rb +13 -0
  83. data/lib/attio/retry_handler.rb +70 -0
  84. data/lib/attio/version.rb +3 -0
  85. data/lib/attio.rb +60 -0
  86. data/run_tests.rb +52 -0
  87. data/test_basic.rb +51 -0
  88. data/test_typhoeus.rb +31 -0
  89. metadata +160 -0
data/README.md ADDED
@@ -0,0 +1,292 @@
1
+ # Attio Ruby Client
2
+
3
+ [![Documentation](https://img.shields.io/badge/docs-yard-blue.svg)](https://idl3.github.io/attio)
4
+ [![Gem Version](https://badge.fury.io/rb/attio.svg)](https://badge.fury.io/rb/attio)
5
+
6
+ Ruby client for the [Attio CRM API](https://developers.attio.com/). This library provides easy access to the Attio API, allowing you to manage records, objects, lists, and more.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'attio'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle install
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install attio
23
+
24
+ ## Quick Start
25
+
26
+ ```ruby
27
+ require 'attio'
28
+
29
+ # Initialize the client with your API key
30
+ client = Attio.client(api_key: 'your-api-key-here')
31
+
32
+ # List people records
33
+ people = client.records.list(object: 'people', limit: 10)
34
+
35
+ # Create a new person
36
+ person = client.records.create(
37
+ object: 'people',
38
+ data: {
39
+ name: 'Jane Doe',
40
+ email: 'jane@example.com',
41
+ phone: '+1-555-0123'
42
+ }
43
+ )
44
+
45
+ # Get a specific person
46
+ person = client.records.get(object: 'people', id: person['id'])
47
+
48
+ # Update a person
49
+ updated_person = client.records.update(
50
+ object: 'people',
51
+ id: person['id'],
52
+ data: { name: 'Jane Smith' }
53
+ )
54
+
55
+ # Delete a person
56
+ client.records.delete(object: 'people', id: person['id'])
57
+ ```
58
+
59
+ ## Usage
60
+
61
+ ### Client Configuration
62
+
63
+ ```ruby
64
+ # Basic client with default timeout (30 seconds)
65
+ client = Attio.client(api_key: 'your-api-key')
66
+
67
+ # Client with custom timeout
68
+ client = Attio::Client.new(api_key: 'your-api-key', timeout: 60)
69
+ ```
70
+
71
+ ### Working with Records
72
+
73
+ #### Listing Records
74
+
75
+ ```ruby
76
+ # List all people
77
+ people = client.records.list(object: 'people')
78
+
79
+ # List with filters
80
+ filtered_people = client.records.list(
81
+ object: 'people',
82
+ filters: {
83
+ name: { contains: 'John' },
84
+ company: { target_object: 'companies', target_record_id: 'company-123' }
85
+ },
86
+ limit: 50
87
+ )
88
+
89
+ # List with sorting
90
+ sorted_people = client.records.list(
91
+ object: 'people',
92
+ sorts: [{ field: 'created_at', direction: 'desc' }],
93
+ limit: 25
94
+ )
95
+ ```
96
+
97
+ #### Creating Records
98
+
99
+ ```ruby
100
+ # Create a person
101
+ person = client.records.create(
102
+ object: 'people',
103
+ data: {
104
+ name: 'John Doe',
105
+ email: 'john@example.com',
106
+ phone: '+1-555-0123',
107
+ company: {
108
+ target_object: 'companies',
109
+ target_record_id: 'company-123'
110
+ }
111
+ }
112
+ )
113
+
114
+ # Create a company
115
+ company = client.records.create(
116
+ object: 'companies',
117
+ data: {
118
+ name: 'Acme Corp',
119
+ domain: 'acme.com',
120
+ industry: 'Technology'
121
+ }
122
+ )
123
+ ```
124
+
125
+ #### Updating Records
126
+
127
+ ```ruby
128
+ # Update a person's email
129
+ client.records.update(
130
+ object: 'people',
131
+ id: 'person-123',
132
+ data: { email: 'newemail@example.com' }
133
+ )
134
+
135
+ # Update multiple fields
136
+ client.records.update(
137
+ object: 'people',
138
+ id: 'person-123',
139
+ data: {
140
+ name: 'John Smith',
141
+ phone: '+1-555-9999',
142
+ notes: 'Updated contact information'
143
+ }
144
+ )
145
+ ```
146
+
147
+ ### Working with Other Resources
148
+
149
+ #### Objects
150
+
151
+ ```ruby
152
+ # List all object types
153
+ objects = client.objects.list
154
+
155
+ # Get a specific object schema
156
+ people_object = client.objects.get(id: 'people')
157
+ ```
158
+
159
+ #### Lists
160
+
161
+ ```ruby
162
+ # List all lists
163
+ lists = client.lists.list
164
+
165
+ # Get entries from a specific list
166
+ entries = client.lists.entries(id: 'list-123')
167
+ ```
168
+
169
+ #### Workspaces
170
+
171
+ ```ruby
172
+ # List workspaces
173
+ workspaces = client.workspaces.list
174
+
175
+ # Get current workspace
176
+ workspace = client.workspaces.get
177
+ ```
178
+
179
+ #### Attributes
180
+
181
+ ```ruby
182
+ # List attributes for an object
183
+ attributes = client.attributes.list(object: 'people')
184
+
185
+ # Create a custom attribute
186
+ attribute = client.attributes.create(
187
+ object: 'people',
188
+ data: {
189
+ title: 'Custom Field',
190
+ api_slug: 'custom_field',
191
+ type: 'text'
192
+ }
193
+ )
194
+ ```
195
+
196
+ #### Users
197
+
198
+ ```ruby
199
+ # List workspace users
200
+ users = client.users.list
201
+
202
+ # Get current user
203
+ user = client.users.me
204
+ ```
205
+
206
+ ### Error Handling
207
+
208
+ The client will raise appropriate exceptions for different error conditions:
209
+
210
+ ```ruby
211
+ begin
212
+ client.records.get(object: 'people', id: 'invalid-id')
213
+ rescue Attio::NotFoundError => e
214
+ puts "Record not found: #{e.message}"
215
+ rescue Attio::AuthenticationError => e
216
+ puts "Authentication failed: #{e.message}"
217
+ rescue Attio::RateLimitError => e
218
+ puts "Rate limit exceeded. Retry after: #{e.retry_after}"
219
+ rescue Attio::APIError => e
220
+ puts "API error: #{e.message}"
221
+ end
222
+ ```
223
+
224
+ ## Configuration Options
225
+
226
+ | Option | Type | Default | Description |
227
+ |--------|------|---------|-------------|
228
+ | `api_key` | String | Required | Your Attio API key |
229
+ | `timeout` | Integer | 30 | Request timeout in seconds |
230
+
231
+ ## API Coverage
232
+
233
+ This client supports all major Attio API endpoints:
234
+
235
+ - ✅ Records (CRUD operations, querying)
236
+ - ✅ Objects (list, get schema)
237
+ - ✅ Lists (list, get entries)
238
+ - ✅ Workspaces (list, get current)
239
+ - ✅ Attributes (list, create, update)
240
+ - ✅ Users (list, get current user)
241
+
242
+ ## Development
243
+
244
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
245
+
246
+ ### Running Tests
247
+
248
+ ```bash
249
+ bundle exec rspec
250
+ ```
251
+
252
+ ### Generating Documentation
253
+
254
+ ```bash
255
+ # Generate YARD documentation
256
+ bundle exec rake docs:generate
257
+
258
+ # Open documentation in browser
259
+ bundle exec rake docs:open
260
+
261
+ # Serve documentation locally
262
+ bundle exec rake docs:serve
263
+ ```
264
+
265
+ ### Code Coverage
266
+
267
+ ```bash
268
+ bundle exec rake coverage:report
269
+ ```
270
+
271
+ ## Contributing
272
+
273
+ Bug reports and pull requests are welcome on GitHub at https://github.com/idl3/attio.
274
+
275
+ 1. Fork the repository
276
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
277
+ 3. Make your changes and add tests
278
+ 4. Ensure all tests pass (`bundle exec rspec`)
279
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
280
+ 6. Push to the branch (`git push origin my-new-feature`)
281
+ 7. Create a new Pull Request
282
+
283
+ ## License
284
+
285
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
286
+
287
+ ## Support
288
+
289
+ - 📖 [API Documentation](https://developers.attio.com/)
290
+ - 🐛 [Issues](https://github.com/idl3/attio/issues)
291
+ - 💬 [Discussions](https://github.com/idl3/attio/discussions)
292
+
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ begin
5
+ require "yard"
6
+ require "yard/rake/yardoc_task"
7
+
8
+ YARD::Rake::YardocTask.new do |t|
9
+ t.files = ['lib/**/*.rb']
10
+ t.options = ['--output-dir', 'docs']
11
+ end
12
+ rescue LoadError
13
+ # YARD is not available
14
+ end
15
+
16
+ RSpec::Core::RakeTask.new(:spec)
17
+
18
+ task default: :spec
19
+
20
+ namespace :coverage do
21
+ desc "Run tests with coverage report"
22
+ task :report do
23
+ ENV['COVERAGE'] = 'true'
24
+ Rake::Task["spec"].execute
25
+ end
26
+ end
27
+
28
+ namespace :docs do
29
+ desc "Generate YARD documentation"
30
+ task :generate do
31
+ if defined?(YARD)
32
+ Rake::Task["yard"].execute
33
+ else
34
+ puts "YARD is not available. Please install it with: gem install yard"
35
+ end
36
+ end
37
+
38
+ desc "Generate and open documentation"
39
+ task :open => :generate do
40
+ if File.exist?("docs/index.html")
41
+ system("open docs/index.html")
42
+ else
43
+ puts "Documentation not found. Run 'rake docs:generate' first."
44
+ end
45
+ end
46
+
47
+ desc "Clean generated documentation"
48
+ task :clean do
49
+ FileUtils.rm_rf("docs") if File.exist?("docs")
50
+ puts "Documentation cleaned."
51
+ end
52
+
53
+ desc "Serve documentation locally (requires 'gem install yard')"
54
+ task :serve do
55
+ system("yard server --reload")
56
+ end
57
+ end
data/SECURITY.md ADDED
@@ -0,0 +1,59 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We release patches for security vulnerabilities. Which versions are eligible for receiving such patches depends on the CVSS v3.0 Rating:
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 1.x.x | :white_check_mark: |
10
+ | < 1.0 | :x: |
11
+
12
+ ## Reporting a Vulnerability
13
+
14
+ If you discover a security vulnerability within this project, please follow these steps:
15
+
16
+ 1. **Do NOT** create a public GitHub issue
17
+ 2. Send details to the maintainers through GitHub Security Advisories
18
+ 3. Include the following in your report:
19
+ - Description of the vulnerability
20
+ - Steps to reproduce
21
+ - Possible impact
22
+ - Suggested fix (if any)
23
+
24
+ ### What to expect
25
+
26
+ - Acknowledgment of your report within 48 hours
27
+ - Regular updates on our progress
28
+ - Credit for responsible disclosure (unless you prefer to remain anonymous)
29
+
30
+ ## Security Best Practices
31
+
32
+ When using this gem:
33
+
34
+ 1. **API Key Management**
35
+ - Never commit API keys to version control
36
+ - Use environment variables or secure credential management
37
+ - Rotate API keys regularly
38
+
39
+ 2. **Dependencies**
40
+ - Keep the gem updated to the latest version
41
+ - Monitor security advisories
42
+ - Use `bundle audit` to check for vulnerable dependencies
43
+
44
+ 3. **Data Handling**
45
+ - Be cautious with sensitive data in logs
46
+ - Use HTTPS for all API communications
47
+ - Implement proper error handling to avoid information leakage
48
+
49
+ ## Security Features
50
+
51
+ This gem includes:
52
+ - Automatic API key masking in logs
53
+ - SSL/TLS verification by default
54
+ - Rate limiting protection
55
+ - Input validation and sanitization
56
+
57
+ ## Contact
58
+
59
+ For security concerns, please use GitHub Security Advisories or contact the maintainers directly through GitHub.
data/attio.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/attio/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "attio"
5
+ spec.version = Attio::VERSION
6
+ spec.authors = ["Ernest Sim"]
7
+ spec.email = ["ernest.codes@gmail.com"]
8
+
9
+ spec.summary = %q{Ruby client for the Attio API}
10
+ spec.description = %q{A Ruby library for interacting with the Attio API, providing easy access to CRM functionality}
11
+ spec.homepage = "https://github.com/idl3/attio"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
14
+
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "typhoeus", "~> 1.4"
31
+
32
+ # Development dependencies
33
+ spec.add_development_dependency "yard", "~> 0.9"
34
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "attio"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/danger/Dangerfile ADDED
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Make it more obvious that a PR is a work in progress and shouldn't be merged yet
4
+ warn("PR is classed as Work in Progress") if github.pr_title.include? "WIP"
5
+
6
+ # Warn when there is a big PR
7
+ warn("Big PR") if git.lines_of_code > 500
8
+
9
+ # Don't let testing shortcuts get into main by accident
10
+ fail("fdescribe left in tests") if `grep -r fdescribe spec/ `.length > 1
11
+ fail("fit left in tests") if `grep -r fit spec/ `.length > 1
12
+
13
+ # Ensure a clean commit history
14
+ if git.commits.any? { |c| c.message =~ /^fixup!/ }
15
+ fail("Please squash fixup! commits before merging")
16
+ end
17
+
18
+ # Check for proper conventional commit format
19
+ if github.pr_title !~ /^(feat|fix|docs|style|refactor|perf|test|chore|ci|build)(\(.+\))?: .+/
20
+ warn("PR title doesn't follow conventional commit format. Please use format: 'type(scope): description'")
21
+ end
22
+
23
+ # Ensure description is present for non-trivial changes
24
+ if github.pr_body.length < 10 && git.lines_of_code > 20
25
+ warn("Please provide a more detailed PR description for changes of this size")
26
+ end
27
+
28
+ # Check if package files have been updated
29
+ package_updated = git.modified_files.include?("attio.gemspec") || git.modified_files.include?("Gemfile")
30
+ if package_updated
31
+ message("📦 Package files have been updated")
32
+ end
33
+
34
+ # Encourage changelog updates for non-trivial changes
35
+ has_app_changes = git.modified_files.any? { |file| file.start_with?("lib/") }
36
+ has_changelog_changes = git.modified_files.include?("CHANGELOG.md")
37
+
38
+ if has_app_changes && !has_changelog_changes
39
+ # Skip for certain PR types
40
+ unless github.pr_title =~ /^(chore|ci|docs|style|test):/
41
+ warn("Consider updating CHANGELOG.md for this change")
42
+ end
43
+ end
44
+
45
+ # Check for TODO comments in the diff
46
+ git.diff.each do |file|
47
+ file.patch.lines.each_with_index do |line, index|
48
+ if line.start_with?("+") && line.include?("TODO")
49
+ warn("TODO comment added", file: file.path, line: index + 1)
50
+ end
51
+ end
52
+ end
53
+
54
+ # Encourage tests for new features
55
+ has_new_features = git.diff.any? { |file| file.patch.include?("+def ") && file.path.start_with?("lib/") }
56
+ has_test_changes = git.modified_files.any? { |file| file.start_with?("spec/") }
57
+
58
+ if has_new_features && !has_test_changes
59
+ warn("New features should include tests")
60
+ end
61
+
62
+ # Check for debugging code
63
+ debugging_patterns = [
64
+ "binding.pry",
65
+ "debugger",
66
+ "puts",
67
+ "p ",
68
+ "pp ",
69
+ "console.log"
70
+ ]
71
+
72
+ git.diff.each do |file|
73
+ debugging_patterns.each do |pattern|
74
+ if file.patch.include?("+") && file.patch.include?(pattern)
75
+ fail("Debugging code found: #{pattern} in #{file.path}")
76
+ end
77
+ end
78
+ end
79
+
80
+ # Encourage documentation for public API changes
81
+ public_api_changes = git.diff.any? do |file|
82
+ file.path.start_with?("lib/") &&
83
+ file.patch.include?("+ def ") &&
84
+ !file.patch.include?("+ def self.") # Skip private class methods
85
+ end
86
+
87
+ if public_api_changes
88
+ message("📝 Public API changes detected. Consider updating documentation.")
89
+ end
90
+
91
+ # Check for secrets or sensitive information
92
+ sensitive_patterns = [
93
+ /api[_-]?key/i,
94
+ /secret/i,
95
+ /password/i,
96
+ /token/i,
97
+ /auth/i
98
+ ]
99
+
100
+ git.diff.each do |file|
101
+ file.patch.lines.each_with_index do |line, index|
102
+ if line.start_with?("+")
103
+ sensitive_patterns.each do |pattern|
104
+ if line.match?(pattern) && !line.include?("# ") # Not a comment
105
+ warn("Potential sensitive information detected", file: file.path, line: index + 1)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ # Performance reminders for certain file types
113
+ performance_sensitive_files = git.modified_files.select { |file| file.include?("client") || file.include?("http") }
114
+ if performance_sensitive_files.any?
115
+ message("⚡ Performance-sensitive files modified. Consider impact on API call efficiency.")
116
+ end
117
+
118
+ # Remind about version bumping for releases
119
+ if git.modified_files.include?("lib/attio/version.rb")
120
+ message("🔖 Version file updated. Don't forget to update CHANGELOG.md and create a release tag.")
121
+ end
data/docs/.nojekyll ADDED
File without changes