air_test 0.1.6.1 → 0.1.6.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 76572704e0d1a8c3abc7e274def6c51611efba858a6f434b6bbfd5f871aedf12
4
- data.tar.gz: 11235311464e8fe0db11323d3f0fee3fb156c676ab4b3b56f7c02abf410a71d0
3
+ metadata.gz: aeac542af7a36bf55e55009d83c49f62c5d671879cb15656e4ba2101c758f163
4
+ data.tar.gz: 6b5a2971a1a08b6857228941fc31c40e07c5f77465346ea1e2bed71435eb17d0
5
5
  SHA512:
6
- metadata.gz: 793c1fd212fcbd747c85abd0130f69dafa849035d4ce69595b72342f119c73f69c9be5f88fe8375e9c439a8be12e96c487f7e93f733f36957163df49d3647d8a
7
- data.tar.gz: dca493fc7c39853ae784be49e4b187e3d8b752b2d0e7306f2532b4b7d71584e185130f922527598b2e07e64633a256173a5c1fb8dca2053aedcc7a53eac9ff6d
6
+ metadata.gz: 1dbbb43370bb38d8927b647e3b3157d3ea57249b56480132fd7ad992675516f8befff20bf8a34d395150700c137cece8d66553a79895a53473c6613eb51ded1c
7
+ data.tar.gz: 6b364dd429c62999dabf9cabe99e934da775ae74958720328d31a463c48d3cacdf446ac1aa332249bc890754534921ea08914bb70efb58c23769052b7014ddb9
data/README.md CHANGED
@@ -106,6 +106,7 @@ tool: notion # Your ticketing tool (notion/jira/monday)
106
106
  auto_pr: 'yes' # Enable auto PR creation
107
107
  dev_assignee: 'your-name' # Default dev assignee
108
108
  interactive_mode: 'yes' # Enable interactive mode by default
109
+ status_filter: 'Not started' # Status filter for tickets to fetch
109
110
  notion:
110
111
  token: ENV["NOTION_TOKEN"]
111
112
  database_id: ENV["NOTION_DATABASE_ID"]
@@ -123,6 +124,20 @@ github:
123
124
  repo: 'your-org/your-repo'
124
125
  ```
125
126
 
127
+ ### Status Filtering
128
+
129
+ AirTest can filter tickets by their status to only process tickets in specific states:
130
+
131
+ - **Notion**: Filter by status like "Not started", "In progress", "Done", "attente de confirmation", etc.
132
+ - **Jira**: Filter by status like "To Do", "In Progress", "Done", etc.
133
+ - **Monday.com**: Filter by status like "Working on it", "Done", "Stuck", etc.
134
+
135
+ You can configure the status filter in three ways:
136
+
137
+ 1. **During setup**: When running `air_test init`, you'll be prompted for the default status filter
138
+ 2. **Environment variable**: Set `AIRTEST_STATUS_FILTER=your_status` in your `.env` file
139
+ 3. **Configuration file**: Edit the `status_filter` field in `.airtest.yml`
140
+
126
141
  ### Rails Initializer (Optional)
127
142
 
128
143
  For Rails projects, you can also create an initializer:
@@ -234,6 +249,7 @@ Show help information and usage examples.
234
249
  NOTION_TOKEN=secret_xxx
235
250
  NOTION_DATABASE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
236
251
  GITHUB_BOT_TOKEN=ghp_xxx
252
+ AIRTEST_STATUS_FILTER=Not started # Optional: Override status filter
237
253
  ```
238
254
 
239
255
  #### For Jira:
@@ -243,6 +259,7 @@ JIRA_PROJECT_ID=your_project_id
243
259
  JIRA_DOMAIN=your_domain.atlassian.net
244
260
  JIRA_EMAIL=your_email@example.com
245
261
  GITHUB_BOT_TOKEN=ghp_xxx
262
+ AIRTEST_STATUS_FILTER=To Do # Optional: Override status filter
246
263
  ```
247
264
 
248
265
  #### For Monday.com:
@@ -251,6 +268,7 @@ MONDAY_TOKEN=your_monday_token
251
268
  MONDAY_BOARD_ID=your_board_id
252
269
  MONDAY_DOMAIN=your_domain.monday.com
253
270
  GITHUB_BOT_TOKEN=ghp_xxx
271
+ AIRTEST_STATUS_FILTER=Working on it # Optional: Override status filter
254
272
  ```
255
273
 
256
274
  ### System Requirements
@@ -266,7 +284,7 @@ GITHUB_BOT_TOKEN=ghp_xxx
266
284
 
267
285
  - **Configuration not found**: Run `air_test init` to set up configuration
268
286
  - **Authentication error**: Check your API tokens in environment variables
269
- - **No tickets found**: Verify your ticketing tool configuration and permissions
287
+ - **No tickets found**: Verify your ticketing tool configuration and permissions, or check if your status filter matches existing ticket statuses
270
288
  - **PR not created**: Make sure the branch contains commits different from `main`
271
289
  - **Permission issues**: Ensure the GitHub bot has access to the repo
272
290
 
data/lib/air_test/cli.rb CHANGED
@@ -9,6 +9,7 @@ module AirTest
9
9
  class CLI
10
10
  def initialize
11
11
  @prompt = TTY::Prompt.new
12
+ load_env_files
12
13
  end
13
14
 
14
15
  def init(silent: false)
@@ -152,26 +153,27 @@ module AirTest
152
153
  end
153
154
 
154
155
  def initialize_airtest_config(config)
155
- # Initialize AirTest configuration with environment variables
156
+ # Initialize AirTest configuration with values from config file
156
157
  AirTest.configure do |airtest_config|
157
158
  case config['tool']
158
159
  when 'notion'
159
- airtest_config.notion[:token] = ENV['NOTION_TOKEN']
160
- airtest_config.notion[:database_id] = ENV['NOTION_DATABASE_ID']
160
+ airtest_config.notion[:token] = config['notion']['token']
161
+ airtest_config.notion[:database_id] = config['notion']['database_id']
161
162
  when 'jira'
162
- airtest_config.jira[:token] = ENV['JIRA_TOKEN']
163
- airtest_config.jira[:project_id] = ENV['JIRA_PROJECT_ID']
164
- airtest_config.jira[:domain] = ENV['JIRA_DOMAIN']
165
- airtest_config.jira[:email] = ENV['JIRA_EMAIL']
163
+ airtest_config.jira[:token] = config['jira']['token']
164
+ airtest_config.jira[:project_id] = config['jira']['project_id']
165
+ airtest_config.jira[:domain] = config['jira']['domain']
166
+ airtest_config.jira[:email] = config['jira']['email']
166
167
  when 'monday'
167
- airtest_config.monday[:token] = ENV['MONDAY_TOKEN']
168
- airtest_config.monday[:board_id] = ENV['MONDAY_BOARD_ID']
169
- airtest_config.monday[:domain] = ENV['MONDAY_DOMAIN']
168
+ airtest_config.monday[:token] = config['monday']['token']
169
+ airtest_config.monday[:board_id] = config['monday']['board_id']
170
+ airtest_config.monday[:domain] = config['monday']['domain']
170
171
  end
171
172
 
172
- airtest_config.github[:token] = ENV['GITHUB_BOT_TOKEN']
173
- airtest_config.repo = ENV['REPO'] || config['github']['repo']
173
+ airtest_config.github[:token] = config['github']['token']
174
+ airtest_config.repo = config['github']['repo']
174
175
  airtest_config.tool = config['tool']
176
+ airtest_config.status_filter = config['status_filter']
175
177
  end
176
178
  end
177
179
 
@@ -186,12 +188,15 @@ module AirTest
186
188
  # Fetch all tickets (we'll filter them later)
187
189
  all_tickets = parser.fetch_tickets(limit: 100)
188
190
 
191
+ puts "#{YELLOW}🔍 Found #{all_tickets.length} total tickets#{RESET}"
192
+
189
193
  # Filter by search if specified
190
194
  if options[:search]
191
195
  all_tickets = all_tickets.select { |ticket|
192
196
  title = parser.extract_ticket_title(ticket)
193
197
  title.downcase.include?(options[:search].downcase)
194
198
  }
199
+ puts "#{YELLOW}🔍 After search filter: #{all_tickets.length} tickets#{RESET}"
195
200
  end
196
201
 
197
202
  # Filter by status (only "Ready" or "Not started" tickets)
@@ -363,12 +368,14 @@ module AirTest
363
368
  auto_pr = @prompt.select("Enable auto PR creation by default?", %w[yes no], default: 'no')
364
369
  dev_assignee = @prompt.ask("Default dev assignee name?", default: 'default_assignee')
365
370
  interactive_mode = @prompt.select("Enable interactive mode by default?", %w[yes no], default: 'no')
371
+ status_filter = @prompt.ask("Default status filter for tickets?", default: 'Not started')
366
372
 
367
373
  {
368
374
  tool: tool,
369
375
  auto_pr: auto_pr,
370
376
  dev_assignee: dev_assignee,
371
- interactive_mode: interactive_mode
377
+ interactive_mode: interactive_mode,
378
+ status_filter: status_filter
372
379
  }
373
380
  end
374
381
 
@@ -385,24 +392,25 @@ module AirTest
385
392
  'auto_pr' => config[:auto_pr],
386
393
  'dev_assignee' => config[:dev_assignee],
387
394
  'interactive_mode' => config[:interactive_mode],
395
+ 'status_filter' => config[:status_filter],
388
396
  'notion' => {
389
- 'token' => 'ENV["NOTION_TOKEN"]',
390
- 'database_id' => 'ENV["NOTION_DATABASE_ID"]'
397
+ 'token' => ENV['NOTION_TOKEN'] || 'your_notion_token',
398
+ 'database_id' => ENV['NOTION_DATABASE_ID'] || 'your_notion_database_id'
391
399
  },
392
400
  'jira' => {
393
- 'token' => 'ENV["JIRA_TOKEN"]',
394
- 'project_id' => 'ENV["JIRA_PROJECT_ID"]',
395
- 'domain' => 'ENV["JIRA_DOMAIN"]',
396
- 'email' => 'ENV["JIRA_EMAIL"]'
401
+ 'token' => ENV['JIRA_TOKEN'] || 'your_jira_token',
402
+ 'project_id' => ENV['JIRA_PROJECT_ID'] || 'your_jira_project_id',
403
+ 'domain' => ENV['JIRA_DOMAIN'] || 'your_jira_domain',
404
+ 'email' => ENV['JIRA_EMAIL'] || 'your_jira_email'
397
405
  },
398
406
  'monday' => {
399
- 'token' => 'ENV["MONDAY_TOKEN"]',
400
- 'board_id' => 'ENV["MONDAY_BOARD_ID"]',
401
- 'domain' => 'ENV["MONDAY_DOMAIN"]'
407
+ 'token' => ENV['MONDAY_TOKEN'] || 'your_monday_token',
408
+ 'board_id' => ENV['MONDAY_BOARD_ID'] || 'your_monday_board_id',
409
+ 'domain' => ENV['MONDAY_DOMAIN'] || 'your_monday_domain'
402
410
  },
403
411
  'github' => {
404
- 'token' => 'ENV["GITHUB_BOT_TOKEN"]',
405
- 'repo' => 'your-org/your-repo'
412
+ 'token' => ENV['GITHUB_BOT_TOKEN'] || 'your_github_token',
413
+ 'repo' => ENV['REPO'] || 'your-org/your-repo'
406
414
  }
407
415
  }
408
416
 
@@ -444,6 +452,7 @@ module AirTest
444
452
  NOTION_TOKEN=your_notion_token
445
453
  NOTION_DATABASE_ID=your_notion_database_id
446
454
  GITHUB_BOT_TOKEN=your_github_token
455
+ AIRTEST_STATUS_FILTER=Not started
447
456
  ENV
448
457
  when 'jira'
449
458
  <<~ENV
@@ -452,6 +461,7 @@ module AirTest
452
461
  JIRA_DOMAIN=your_jira_domain
453
462
  JIRA_EMAIL=your_jira_email
454
463
  GITHUB_BOT_TOKEN=your_github_token
464
+ AIRTEST_STATUS_FILTER=To Do
455
465
  ENV
456
466
  when 'monday'
457
467
  <<~ENV
@@ -459,6 +469,7 @@ module AirTest
459
469
  MONDAY_BOARD_ID=your_monday_board_id
460
470
  MONDAY_DOMAIN=your_monday_domain
461
471
  GITHUB_BOT_TOKEN=your_github_token
472
+ AIRTEST_STATUS_FILTER=Working on it
462
473
  ENV
463
474
  end
464
475
 
@@ -512,6 +523,35 @@ module AirTest
512
523
  end
513
524
  end
514
525
 
526
+ private
527
+
528
+ def load_env_files
529
+ # Try to load .env files in order of preference
530
+ env_files = ['.env.airtest', '.env']
531
+
532
+ env_files.each do |env_file|
533
+ if File.exist?(env_file)
534
+ load_env_file(env_file)
535
+ puts "#{GREEN}✅ Loaded environment variables from #{env_file}#{RESET}" if ENV['AIRTEST_DEBUG']
536
+ break
537
+ end
538
+ end
539
+ end
540
+
541
+ def load_env_file(file_path)
542
+ File.readlines(file_path).each do |line|
543
+ line.strip!
544
+ next if line.empty? || line.start_with?('#')
545
+
546
+ if line.include?('=')
547
+ key, value = line.split('=', 2)
548
+ ENV[key.strip] = value.strip.gsub(/^["']|["']$/, '') # Remove quotes
549
+ end
550
+ end
551
+ rescue => e
552
+ puts "#{YELLOW}⚠️ Warning: Could not load #{file_path}: #{e.message}#{RESET}" if ENV['AIRTEST_DEBUG']
553
+ end
554
+
515
555
  # Color constants
516
556
  GREEN = "\e[32m"
517
557
  YELLOW = "\e[33m"
@@ -4,7 +4,7 @@
4
4
  module AirTest
5
5
  # Handles configuration for AirTest, including API tokens and environment variables.
6
6
  class Configuration
7
- attr_accessor :tool, :notion, :jira, :monday, :github, :repo
7
+ attr_accessor :tool, :notion, :jira, :monday, :github, :repo, :status_filter
8
8
 
9
9
  def initialize
10
10
  @tool = ENV.fetch("AIRTEST_TOOL", "notion")
@@ -27,6 +27,7 @@ module AirTest
27
27
  token: ENV["GITHUB_BOT_TOKEN"] || ENV.fetch("GITHUB_TOKEN", nil)
28
28
  }
29
29
  @repo = ENV.fetch("REPO", nil)
30
+ @status_filter = ENV.fetch("AIRTEST_STATUS_FILTER", "Not started")
30
31
  end
31
32
 
32
33
  def validate!
@@ -12,6 +12,7 @@ module AirTest
12
12
  def initialize(config = AirTest.configuration)
13
13
  @database_id = config.notion[:database_id]
14
14
  @notion_token = config.notion[:token]
15
+ @status_filter = config.status_filter || "Not started"
15
16
  @base_url = "https://api.notion.com/v1"
16
17
  end
17
18
 
@@ -22,16 +23,29 @@ module AirTest
22
23
  page_size: 100,
23
24
  filter: {
24
25
  property: "Status",
25
- select: {
26
- equals: "Not started"
26
+ status: {
27
+ equals: @status_filter
27
28
  }
28
29
  }
29
30
  }
31
+
30
32
  response = make_api_request(uri, request_body)
33
+
31
34
  return [] unless response.code == "200"
32
35
 
33
36
  data = JSON.parse(response.body)
34
- data["results"].first(limit)
37
+ results = data["results"].first(limit)
38
+
39
+ # Debug: Show the first ticket's properties to understand the structure
40
+ if ENV['AIRTEST_DEBUG'] && results.any?
41
+ first_ticket = results.first
42
+ puts "🔍 Debug: First ticket properties:"
43
+ first_ticket["properties"].each do |prop_name, prop_value|
44
+ puts " - #{prop_name}: #{prop_value['type']}"
45
+ end
46
+ end
47
+
48
+ results
35
49
  end
36
50
 
37
51
  def parse_ticket_content(page_id)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AirTest
4
- VERSION = "0.1.6.1"
4
+ VERSION = "0.1.6.3"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: air_test
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6.1
4
+ version: 0.1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - julien bouland
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-07-29 00:00:00.000000000 Z
10
+ date: 2025-07-30 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails