ground_control-api 0.1.0 → 0.2.0

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: fa4151207335fd8c45c84426ef8743b3291149dc545d093537c94237ec29a7f5
4
- data.tar.gz: 3a5f9fcbc1939b84be71dea74a914039c5a8bbfd0f5ec60e50e1d6bdd6de1e98
3
+ metadata.gz: 026bb4b5dc13392c07a775010344d1e1dbd7640b2f5febe49ea4975809ff6dda
4
+ data.tar.gz: 12f6932095b0d846529fb3fdf07313ea3407e34d8b65ddf082f1a29ab169091e
5
5
  SHA512:
6
- metadata.gz: 7fdc683e0ba9125b04fa84d18329719a84e40aa8226d9681f9287658f0e636dadb8c401223dadfde2aafbd9e7340bbcc451f933d708c74f1e85c8284e9a84667
7
- data.tar.gz: dd589635c37e608fe4be787a1e039540da9bdf6dd31f5cc3b94bc5aded654020b2bcaa43c29c271647f6fe777defb3729dac3390254d0d800b22a81311b6d14d
6
+ metadata.gz: 4eab1dfa005e1191e97c5628145ece788fb526d1a2170fc71873eb2a9bc18c1d1a40fb4c7c5ef6ee8bfcab004e04257a01f4c74702acced3a8d73c660945ae95
7
+ data.tar.gz: e01c42d911488fd9a4a3c71f692d895b6b282f944eb76ad1a154e0834b49f1503d40b29761e0f6c76f5a0d8fa87768fe45ff46eca1b39386e299181cdf4106c2
data/.editorconfig ADDED
@@ -0,0 +1,16 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 2
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
13
+
14
+ [Makefile]
15
+ indent_style = tab
16
+ tab_width = 4
@@ -5,55 +5,23 @@ on:
5
5
  push:
6
6
  branches: [ main ]
7
7
 
8
- concurrency:
9
- group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
10
- cancel-in-progress: true
11
-
12
8
  permissions:
13
9
  contents: read
14
10
  pull-requests: read
15
11
 
16
12
  jobs:
17
- lint:
18
- runs-on: ubuntu-latest
19
- timeout-minutes: 10
20
- steps:
21
- - name: Checkout code
22
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
23
-
24
- - name: Set up Ruby
25
- uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0
26
- with:
27
- ruby-version: 3.4.4
28
- bundler-cache: true
29
-
30
- - name: Security scan with Brakeman
31
- run: bundle exec brakeman --no-pager --quiet
32
- - name: Audit gem dependencies for CVEs (bundler-audit)
33
- run: bundle exec bundler-audit check --update
34
- - name: Lint code for consistent style
35
- run: bundle exec rubocop -f github
36
-
37
- test:
38
- runs-on: ubuntu-latest
39
- timeout-minutes: 15
40
-
41
- steps:
42
- - name: Checkout code
43
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
44
-
45
- - name: Set up Ruby
46
- uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0
47
- with:
48
- ruby-version: 3.4.4
49
- bundler-cache: true
50
-
51
- - name: Run tests
52
- env:
53
- RAILS_ENV: test
54
- run: |
55
- if find spec -name '*_spec.rb' 2>/dev/null | grep -q .; then
56
- bundle exec rspec
57
- else
58
- echo "No spec files found, skipping."
59
- fi
13
+ ci:
14
+ uses: rarebit-one/.github/.github/workflows/reusable-gem-ci.yml@v1
15
+ with:
16
+ ruby-versions: '["4.0.0","4.0.1","4.0.2","4.0.3"]'
17
+ lint-ruby-version: "4.0.3"
18
+ lint-command: bundle exec rubocop --config .rubocop.yml -f github
19
+ extra-lint-commands: |
20
+ bundle exec brakeman --no-pager --quiet
21
+ bundle exec bundler-audit check --update
22
+ test-command: |
23
+ if find spec -name '*_spec.rb' 2>/dev/null | grep -q .; then
24
+ bundle exec rspec
25
+ else
26
+ echo "No spec files found, skipping."
27
+ fi
@@ -0,0 +1,27 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: "0 6 * * 1"
10
+
11
+ permissions:
12
+ contents: read
13
+ security-events: write
14
+
15
+ jobs:
16
+ analyze:
17
+ name: Analyze (Ruby)
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
21
+ - uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4
22
+ with:
23
+ languages: ruby
24
+ - uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4
25
+ with:
26
+ category: "/language:ruby"
27
+
@@ -5,85 +5,12 @@ on:
5
5
  tags:
6
6
  - "v*"
7
7
 
8
- permissions:
9
- contents: write
10
-
11
8
  jobs:
12
- # CI is not gated here — branch protection ensures CI passes before
13
- # merge to main, and tags are only pushed after the version bump PR
14
- # is merged. Running CI again on tag push is redundant.
15
9
  release:
16
- runs-on: ubuntu-latest
17
- timeout-minutes: 10
18
- steps:
19
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
20
-
21
- - name: Set up Ruby
22
- uses: ruby/setup-ruby@v1
23
- with:
24
- ruby-version: "3.4.4"
25
-
26
- - name: Verify tag matches gem version
27
- run: |
28
- tag_version="${GITHUB_REF_NAME#v}"
29
- gem_version=$(ruby -e "spec = Gem::Specification.load(Dir['*.gemspec'].first); puts spec.version")
30
- if [ "$tag_version" != "$gem_version" ]; then
31
- echo "::error::Tag version ($tag_version) does not match gemspec version ($gem_version)"
32
- exit 1
33
- fi
34
-
35
- - name: Extract changelog entry
36
- id: changelog
37
- run: |
38
- version="${GITHUB_REF_NAME#v}"
39
- notes=$(awk -v ver="$version" '
40
- /^## \[/ {
41
- if (found) exit
42
- if ($0 ~ "^## \\[" ver "\\]") found=1
43
- next
44
- }
45
- found { print }
46
- ' CHANGELOG.md)
47
-
48
- if [ -z "$notes" ]; then
49
- echo "::error::No CHANGELOG.md entry found for version $version"
50
- exit 1
51
- fi
52
-
53
- # Use a random delimiter to prevent injection via changelog content
54
- delimiter="EOF_$(openssl rand -hex 8)"
55
- {
56
- echo "notes<<${delimiter}"
57
- echo "$notes"
58
- echo "${delimiter}"
59
- } >> "$GITHUB_OUTPUT"
60
-
61
- - name: Create GitHub Release
62
- env:
63
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
64
- RELEASE_NOTES: ${{ steps.changelog.outputs.notes }}
65
- run: |
66
- printf "%s" "$RELEASE_NOTES" > /tmp/release_notes.txt
67
- gh release create "$GITHUB_REF_NAME" \
68
- --title "$GITHUB_REF_NAME" \
69
- --notes-file /tmp/release_notes.txt
70
-
71
- publish:
72
- needs: release
73
- runs-on: ubuntu-latest
74
- timeout-minutes: 10
75
- environment: rubygems
10
+ uses: rarebit-one/.github/.github/workflows/reusable-gem-release.yml@v1
11
+ with:
12
+ gem-name: ground_control-api
13
+ ruby-version: "4.0.1"
76
14
  permissions:
77
- contents: read
15
+ contents: write
78
16
  id-token: write
79
- steps:
80
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
81
-
82
- - name: Set up Ruby
83
- uses: ruby/setup-ruby@v1
84
- with:
85
- ruby-version: "3.4.4"
86
- bundler-cache: true
87
-
88
- - name: Push to RubyGems
89
- uses: rubygems/release-gem@6317d8d1f7e28c24d28f6eff169ea854948bd9f7 # v1.2.0
data/AGENTS.md ADDED
@@ -0,0 +1,173 @@
1
+ # AGENTS.md - AI Agent Guide for GroundControl::Api
2
+
3
+ GroundControl::Api is a Rails engine providing a headless JSON API for
4
+ managing Active Job queues, jobs, workers, and recurring tasks on top of
5
+ `mission_control-jobs`. It is the foundation for `ground_control-inertia`
6
+ (which adds an Inertia.js + React UI) but can be used standalone.
7
+
8
+ ## Quick Reference
9
+
10
+ ```bash
11
+ # Run the full spec suite
12
+ bundle exec rspec
13
+
14
+ # Run a single spec file
15
+ bundle exec rspec spec/path/to/foo_spec.rb
16
+
17
+ # Lint
18
+ bundle exec rubocop
19
+
20
+ # Auto-fix lint issues
21
+ bundle exec rubocop -A
22
+
23
+ # Security checks
24
+ bundle exec brakeman --no-pager
25
+ bundle exec bundler-audit --update
26
+ ```
27
+
28
+ `Gemfile.lock` is gitignored — `bundle install` regenerates it locally and
29
+ in CI.
30
+
31
+ ## Project Structure
32
+
33
+ ```
34
+ ground_control-api/
35
+ ├── app/
36
+ │ ├── controllers/ground_control/api/
37
+ │ │ ├── application_controller.rb # JSON API base
38
+ │ │ ├── applications_controller.rb # Mission Control applications
39
+ │ │ ├── queues_controller.rb # Queue listing + pause toggle
40
+ │ │ ├── queues/pauses_controller.rb # Nested pause/resume action
41
+ │ │ ├── jobs_controller.rb # Job index/show
42
+ │ │ ├── retries_controller.rb # Single-job retry
43
+ │ │ ├── bulk_retries_controller.rb # Bulk retry
44
+ │ │ ├── discards_controller.rb # Single-job discard
45
+ │ │ ├── bulk_discards_controller.rb # Bulk discard
46
+ │ │ ├── dispatches_controller.rb # Force-dispatch scheduled jobs
47
+ │ │ ├── workers_controller.rb # Worker process listing
48
+ │ │ ├── recurring_tasks_controller.rb # Recurring task listing
49
+ │ │ ├── features_controller.rb # Adapter capability flags
50
+ │ │ └── concerns/ # error_handling, job_filters,
51
+ │ │ # adapter_features
52
+ │ └── resources/ground_control/api/
53
+ │ ├── application_resource.rb # Alba serializers
54
+ │ ├── base_resource.rb
55
+ │ ├── job_resource.rb
56
+ │ ├── page_resource.rb # Pagination wrapper
57
+ │ ├── queue_resource.rb
58
+ │ ├── recurring_task_resource.rb
59
+ │ ├── server_resource.rb # Worker/server detail
60
+ │ └── worker_resource.rb
61
+ ├── config/
62
+ │ └── routes.rb # JSON API surface
63
+ ├── lib/ground_control/api/
64
+ │ ├── engine.rb # Wires middleware, requires
65
+ │ │ # mission_control-jobs engine
66
+ │ └── version.rb
67
+ └── spec/
68
+ └── spec_helper.rb
69
+ ```
70
+
71
+ ## Key Patterns
72
+
73
+ ### Engine boot
74
+
75
+ `GroundControl::Api::Engine` isolates the `GroundControl::Api` namespace and
76
+ requires `mission_control/jobs/engine` after initialize so all of Mission
77
+ Control's Active Record-style models are available without forcing the host
78
+ app to mount the upstream UI engine. `ActionDispatch::Flash` and
79
+ `Rack::MethodOverride` are inserted as middleware so the API can be mounted
80
+ under the same Rails stack as a host app without surprise.
81
+
82
+ ### Resources (Alba)
83
+
84
+ Every JSON response goes through an Alba resource under
85
+ `app/resources/ground_control/api/`. `ApplicationResource` is the base for
86
+ gem-specific concerns; individual resources (e.g. `JobResource`,
87
+ `QueueResource`) define the public attribute set. `PageResource` wraps a
88
+ collection plus pagination metadata for index endpoints.
89
+
90
+ ### Controllers
91
+
92
+ Controllers inherit from `GroundControl::Api::ApplicationController`, which
93
+ forces JSON responses and includes the `ErrorHandling`, `JobFilters`, and
94
+ `AdapterFeatures` concerns. Mutation endpoints (retries, discards,
95
+ dispatches, queue pauses) are namespaced as separate controllers per REST
96
+ resource rather than as custom actions on the parent.
97
+
98
+ ### Adapter feature detection
99
+
100
+ `AdapterFeatures` exposes which capabilities the active Active Job adapter
101
+ supports (e.g. recurring tasks, bulk operations). The `FeaturesController`
102
+ returns this map so a UI client can hide controls the underlying queue
103
+ backend cannot service.
104
+
105
+ ## Common Workflows
106
+
107
+ ### Adding a new endpoint
108
+
109
+ 1. Add the route under `config/routes.rb` inside the engine's namespace.
110
+ 2. Create or extend a controller under `app/controllers/ground_control/api/`.
111
+ 3. Define an Alba resource for the response shape under
112
+ `app/resources/ground_control/api/`.
113
+ 4. Add a request spec under `spec/requests/`.
114
+
115
+ ### Running against a host app
116
+
117
+ The engine assumes Rails 8.0+ and `mission_control-jobs >= 0.6`. Mount it
118
+ in a host app with:
119
+
120
+ ```ruby
121
+ mount GroundControl::Api::Engine, at: "/ground_control/api"
122
+ ```
123
+
124
+ The host app provides the Active Job adapter, queue store, and any
125
+ authentication via Rails' standard middleware stack — this engine
126
+ intentionally has no auth opinions.
127
+
128
+ ## Testing
129
+
130
+ - RSpec via `rspec-rails`. `spec/spec_helper.rb` is currently minimal —
131
+ request specs that drive the engine through a dummy host app should be
132
+ added under `spec/requests/`.
133
+ - Lefthook pre-push runs whitespace + signature checks, RuboCop on `*.rb`,
134
+ and `rspec --fail-fast`.
135
+
136
+ ## Security Notes
137
+
138
+ - Brakeman and bundler-audit run in CI (`extra-lint-commands` of the
139
+ reusable `reusable-gem-ci.yml@v1` workflow) and as pre-push lefthook
140
+ steps.
141
+ - The engine deliberately ships no authentication — host apps are
142
+ responsible for protecting the mount point with their existing auth
143
+ middleware.
144
+
145
+ ## Key Files
146
+
147
+ | File | Purpose |
148
+ |-----------------------------------------------------|-------------------------------------------------|
149
+ | `lib/ground_control/api/engine.rb` | Engine wiring + middleware |
150
+ | `lib/ground_control/api/version.rb` | Gem version |
151
+ | `app/controllers/ground_control/api/application_controller.rb` | JSON API base controller |
152
+ | `app/controllers/concerns/ground_control/api/error_handling.rb`| Shared rescue + JSON error shape |
153
+ | `app/controllers/concerns/ground_control/api/job_filters.rb` | Index filtering / sorting |
154
+ | `app/controllers/concerns/ground_control/api/adapter_features.rb` | Capability detection |
155
+ | `app/resources/ground_control/api/application_resource.rb` | Alba base resource |
156
+ | `app/resources/ground_control/api/page_resource.rb` | Pagination wrapper |
157
+ | `config/routes.rb` | JSON API surface |
158
+ | `.github/workflows/ci.yml` | Reusable CI shim |
159
+ | `.github/workflows/release.yml` | Reusable release shim |
160
+ | `lefthook.yml` | Pre-push hooks |
161
+
162
+ ## Dependencies
163
+
164
+ - **rails** — `>= 8.0`
165
+ - **mission_control-jobs** — `>= 0.6`
166
+ - **alba** — `>= 3.0` (JSON serialization)
167
+
168
+ Dev / test:
169
+
170
+ - **rspec-rails** — test framework
171
+ - **rubocop-rails-omakase** — linting
172
+ - **brakeman**, **bundler-audit** — security scanners
173
+ - **lefthook** — git hook manager
data/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.0] - 2026-04-29
11
+
12
+ ### Changed
13
+
14
+ - CI and release workflows migrated to the shared `rarebit-one/.github` reusable workflows (`reusable-gem-ci.yml@v1`, `reusable-gem-release.yml@v1`); `.github/workflows/ci.yml` and `release.yml` are now thin shims.
15
+
16
+ ### Removed
17
+
18
+ - **BREAKING:** Dropped support for Ruby < 4.0. `required_ruby_version` is now `>= 4.0` (was `>= 3.2`). Hosts must upgrade to Ruby 4.0+ before bundling this version. CI tests all four published 4.0.x patches. Aligns with the org-wide Ruby 4 policy ([rarebit-one/standard_id#195](https://github.com/rarebit-one/standard_id/pull/195)).
19
+ - **BREAKING:** Dropped support for Rails < 8.0. The `rails` constraint is now `>= 8.0` (was `>= 7.1`). Hosts on Rails 7.x must upgrade to Rails 8.0+ before bundling this version. Aligns with the org-wide policy of supporting Rails 8 and up.
20
+
10
21
  ## [0.1.0] - 2026-04-21
11
22
 
12
23
  ### Added
data/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  A headless JSON API Rails engine for managing Active Job queues, jobs, workers, and recurring tasks. Built on top of [mission_control-jobs](https://github.com/rails/mission_control-jobs) for the adapter and query layer.
4
4
 
5
- Use standalone for custom frontends, or as the foundation for [ground_control-inertia](https://github.com/rarebit-one/ground-control-inertia).
5
+ Use standalone for custom frontends, or as the foundation for [ground_control-inertia](https://github.com/rarebit-one/ground_control-inertia).
6
6
 
7
7
  ## Installation
8
8
 
9
9
  ```ruby
10
10
  # Gemfile
11
- gem "ground_control-api", github: "rarebit-one/ground-control-api"
11
+ gem "ground_control-api", github: "rarebit-one/ground_control-api"
12
12
  ```
13
13
 
14
14
  ## Setup
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GroundControl
4
4
  module Api
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "simplecov"
4
+ SimpleCov.start do
5
+ enable_coverage :branch
6
+ add_filter "/spec/"
7
+ end
8
+
3
9
  RSpec.configure do |config|
4
10
  config.expect_with :rspec do |expectations|
5
11
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ground_control-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jaryl Sim
@@ -43,14 +43,28 @@ dependencies:
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '7.1'
46
+ version: '8.0'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '7.1'
53
+ version: '8.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: simplecov
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.22'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.22'
54
68
  description: A Rails engine providing a JSON API layer on top of mission_control-jobs.
55
69
  Use standalone or as the foundation for ground_control-inertia.
56
70
  email:
@@ -59,11 +73,13 @@ executables: []
59
73
  extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
76
+ - ".editorconfig"
62
77
  - ".github/dependabot.yml"
63
78
  - ".github/workflows/ci.yml"
64
79
  - ".github/workflows/claude-code-review.yml"
65
80
  - ".github/workflows/claude.yml"
66
81
  - ".github/workflows/codeql-actions.yml"
82
+ - ".github/workflows/codeql.yml"
67
83
  - ".github/workflows/release.yml"
68
84
  - ".lefthook/bundle-sync.sh"
69
85
  - ".lefthook/lib/git-upstream.sh"
@@ -71,6 +87,7 @@ files:
71
87
  - ".lefthook/whitespace-check.sh"
72
88
  - ".rspec"
73
89
  - ".ruby-version"
90
+ - AGENTS.md
74
91
  - CHANGELOG.md
75
92
  - CLAUDE.md
76
93
  - MIT-LICENSE
@@ -107,14 +124,14 @@ files:
107
124
  - lib/ground_control/api/version.rb
108
125
  - sig/ground_control/api.rbs
109
126
  - spec/spec_helper.rb
110
- homepage: https://github.com/rarebit-one/ground-control-api
127
+ homepage: https://github.com/rarebit-one/ground_control-api
111
128
  licenses:
112
129
  - MIT
113
130
  metadata:
114
- homepage_uri: https://github.com/rarebit-one/ground-control-api
115
- source_code_uri: https://github.com/rarebit-one/ground-control-api
116
- changelog_uri: https://github.com/rarebit-one/ground-control-api/blob/main/CHANGELOG.md
117
- bug_tracker_uri: https://github.com/rarebit-one/ground-control-api/issues
131
+ homepage_uri: https://github.com/rarebit-one/ground_control-api
132
+ source_code_uri: https://github.com/rarebit-one/ground_control-api
133
+ changelog_uri: https://github.com/rarebit-one/ground_control-api/blob/main/CHANGELOG.md
134
+ bug_tracker_uri: https://github.com/rarebit-one/ground_control-api/issues
118
135
  rdoc_options: []
119
136
  require_paths:
120
137
  - lib
@@ -122,14 +139,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
139
  requirements:
123
140
  - - ">="
124
141
  - !ruby/object:Gem::Version
125
- version: 3.2.0
142
+ version: '4.0'
126
143
  required_rubygems_version: !ruby/object:Gem::Requirement
127
144
  requirements:
128
145
  - - ">="
129
146
  - !ruby/object:Gem::Version
130
147
  version: '0'
131
148
  requirements: []
132
- rubygems_version: 3.6.7
149
+ rubygems_version: 4.0.3
133
150
  specification_version: 4
134
151
  summary: Headless JSON API for managing Active Job queues, jobs, workers, and recurring
135
152
  tasks