collavre_github 0.4.1 → 0.5.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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/collavre_github/creatives/integrations_controller.rb +61 -12
  3. data/app/controllers/collavre_github/webhooks_controller.rb +25 -4
  4. data/app/javascript/collavre_github.js +706 -0
  5. data/app/jobs/collavre_github/initial_markdown_sync_job.rb +19 -0
  6. data/app/jobs/collavre_github/markdown_sync_job.rb +16 -0
  7. data/app/models/collavre_github/repository_link.rb +7 -0
  8. data/app/services/collavre_github/client.rb +50 -0
  9. data/app/services/collavre_github/markdown_sync/content_processor.rb +113 -0
  10. data/app/services/collavre_github/markdown_sync/incremental_sync_service.rb +231 -0
  11. data/app/services/collavre_github/markdown_sync/initial_import_service.rb +190 -0
  12. data/app/services/collavre_github/tools/concerns/github_client_finder.rb +17 -0
  13. data/app/services/collavre_github/tools/github_pr_commits_service.rb +7 -10
  14. data/app/services/collavre_github/tools/github_pr_details_service.rb +21 -24
  15. data/app/services/collavre_github/tools/github_pr_diff_service.rb +13 -16
  16. data/app/services/collavre_github/webhook_provisioner.rb +18 -3
  17. data/app/views/collavre_github/auth/setup.html.erb +48 -3
  18. data/app/views/collavre_github/integrations/_modal.html.erb +18 -3
  19. data/config/locales/en.yml +9 -0
  20. data/config/locales/ko.yml +9 -0
  21. data/config/routes.rb +3 -1
  22. data/db/migrate/20260412000000_add_markdown_sync_to_repository_links.rb +10 -0
  23. data/db/migrate/20260416000000_add_markdown_root_creative_index.rb +5 -0
  24. data/lib/collavre_github/version.rb +1 -1
  25. data/lib/tasks/mock_import.rake +98 -0
  26. metadata +10 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c11fdb398224bc3a5dfeeb326b2f5ddd1575c1a371907ce0fcb9d5592e2f9cf
4
- data.tar.gz: '058cfbcf2a41677dd39ec6da17f3b8f31471875db56e158855f587985e26005b'
3
+ metadata.gz: 6fb4ed5d918d784abb2dbfcaf6618391b4e1f888ccd166844db4bd823dce2e08
4
+ data.tar.gz: 9d569c3485a15ae9a282c2857bf8e30a3928e30f50fe9efa6e1ab13f12d2fe7d
5
5
  SHA512:
6
- metadata.gz: c9063bc158175ca780be591a837e7b185eb2e6fc7595422c4f52b17ae91c5f459246521ccaa0eac5d6dbb2de2b6fda1331f0df59cbab16730f7112b06eb780ff
7
- data.tar.gz: 1fbcc7a46e22b45146a812335524dcd3a08ec10b2cc21d6f7588978a4a3960fad36b7fd6f680a29c30b632f44cf3367f230c78cbde588bc0342ade2c69a908c1
6
+ metadata.gz: ed515fb1cd7ea7481ec30269b871b792a74c8a30d780abe4fb5473bf478111937f8748a60e4a432928aa7dbe75f8bef8fc8f1f91bacbd809b8b6367012b91f4a
7
+ data.tar.gz: 4ffb6a588103ddf1865539e93bff437d8ead4187354e0c4807707248d6f773bd49245d96cde837b6c02330f508ff4b7108da687f298a73d43e546f0f27419180
@@ -1,12 +1,13 @@
1
1
  module CollavreGithub
2
2
  module Creatives
3
3
  class IntegrationsController < ApplicationController
4
+ include Collavre::IntegrationSetup
4
5
  include Collavre::IntegrationPermission
5
6
 
6
7
  before_action :set_creative
7
8
  before_action :set_origin
8
9
  before_action :ensure_read_permission
9
- before_action :ensure_admin_permission, only: [ :show, :update ]
10
+ before_action :ensure_admin_permission, only: [ :show, :update, :resync ]
10
11
 
11
12
  def show
12
13
  account = Current.user.github_account
@@ -25,7 +26,14 @@ module CollavreGithub
25
26
  },
26
27
  selected_repositories: links.map(&:repository_full_name),
27
28
  all_repositories: all_repositories,
28
- webhooks: serialize_webhooks(links)
29
+ webhooks: serialize_webhooks(links),
30
+ markdown_sync: links.each_with_object({}) { |l, h|
31
+ h[l.repository_full_name] = {
32
+ enabled: l.markdown_sync_enabled?,
33
+ last_synced_at: l.last_synced_at,
34
+ sync_branch: l.markdown_sync_branch
35
+ }
36
+ }
29
37
  }
30
38
  end
31
39
 
@@ -56,6 +64,24 @@ module CollavreGithub
56
64
  links = linked_repository_links(account).to_a
57
65
  end
58
66
 
67
+ # Handle markdown sync toggle BEFORE webhook provisioning
68
+ # so events_for() sees the updated markdown_sync_enabled state
69
+ markdown_sync = integration_attributes[:markdown_sync]
70
+ if markdown_sync.is_a?(ActionController::Parameters) || markdown_sync.is_a?(Hash)
71
+ links.each do |link|
72
+ repo = link.repository_full_name
73
+ next unless markdown_sync.key?(repo)
74
+
75
+ enabled = ActiveModel::Type::Boolean.new.cast(markdown_sync[repo])
76
+ was_enabled = link.markdown_sync_enabled?
77
+ link.update!(markdown_sync_enabled: enabled)
78
+
79
+ if enabled && !was_enabled
80
+ CollavreGithub::InitialMarkdownSyncJob.perform_later(link.id)
81
+ end
82
+ end
83
+ end
84
+
59
85
  CollavreGithub::WebhookProvisioner.ensure_for_links(
60
86
  account: account,
61
87
  links: links,
@@ -65,12 +91,43 @@ module CollavreGithub
65
91
  render json: {
66
92
  success: true,
67
93
  selected_repositories: links.map(&:repository_full_name),
68
- webhooks: serialize_webhooks(links)
94
+ webhooks: serialize_webhooks(links),
95
+ markdown_sync: links.each_with_object({}) { |l, h|
96
+ h[l.repository_full_name] = {
97
+ enabled: l.markdown_sync_enabled?,
98
+ last_synced_at: l.last_synced_at,
99
+ sync_branch: l.markdown_sync_branch
100
+ }
101
+ }
69
102
  }
70
103
  rescue ActiveRecord::RecordInvalid => e
71
104
  render json: { error: e.message }, status: :unprocessable_entity
72
105
  end
73
106
 
107
+ def resync
108
+ account = Current.user.github_account
109
+ unless account
110
+ render json: { error: I18n.t("collavre_github.errors.not_connected") }, status: :unprocessable_entity
111
+ return
112
+ end
113
+
114
+ repo = params[:repository]
115
+ link = linked_repository_links(account).find_by(repository_full_name: repo)
116
+ unless link&.markdown_sync_enabled?
117
+ render json: { error: I18n.t("collavre_github.markdown_sync.not_enabled") }, status: :unprocessable_entity
118
+ return
119
+ end
120
+
121
+ # Archive existing synced tree and re-import
122
+ if link.markdown_root_creative
123
+ link.markdown_root_creative.archive! if link.markdown_root_creative.respond_to?(:archive!)
124
+ link.update!(markdown_root_creative_id: nil)
125
+ end
126
+
127
+ CollavreGithub::InitialMarkdownSyncJob.perform_later(link.id)
128
+ render json: { success: true, message: I18n.t("collavre_github.markdown_sync.resync_started") }
129
+ end
130
+
74
131
  def destroy
75
132
  unless @creative.has_permission?(Current.user, :write)
76
133
  render json: { error: integration_forbidden_message }, status: :forbidden
@@ -139,14 +196,6 @@ module CollavreGithub
139
196
 
140
197
  private
141
198
 
142
- def set_creative
143
- @creative = Collavre::Creative.find(params[:creative_id])
144
- end
145
-
146
- def set_origin
147
- @origin = @creative.effective_origin
148
- end
149
-
150
199
  def integration_forbidden_message
151
200
  I18n.t("collavre_github.errors.forbidden")
152
201
  end
@@ -158,7 +207,7 @@ module CollavreGithub
158
207
  end
159
208
 
160
209
  def integration_params
161
- params.permit(repositories: [])
210
+ params.permit(repositories: [], markdown_sync: {})
162
211
  end
163
212
 
164
213
  def serialize_webhooks(links)
@@ -13,7 +13,13 @@ module CollavreGithub
13
13
  return head :unauthorized unless valid_signature?(raw_body)
14
14
 
15
15
  payload = payload.presence || {}
16
- create_system_comment(event, payload) if @repository_link&.creative
16
+
17
+ # Process all links for this repo (same repo can be linked to multiple creatives)
18
+ all_links = all_repository_links_for(payload)
19
+ all_links.each do |link|
20
+ create_system_comment_for(link, event, payload) if link.creative
21
+ trigger_markdown_sync_for(link, event, payload) if link.markdown_sync_enabled?
22
+ end
17
23
 
18
24
  head :ok
19
25
  rescue JSON::ParserError
@@ -22,8 +28,8 @@ module CollavreGithub
22
28
 
23
29
  private
24
30
 
25
- def create_system_comment(event, payload)
26
- creative = @repository_link.creative&.effective_origin
31
+ def create_system_comment_for(link, event, payload)
32
+ creative = link.creative&.effective_origin
27
33
  return unless creative
28
34
 
29
35
  content = format_github_event(event, payload)
@@ -33,7 +39,6 @@ module CollavreGithub
33
39
  content: content,
34
40
  private: false
35
41
  )
36
- # Dispatch handled by Comment#after_create_commit (skipped for system messages with user: nil)
37
42
  end
38
43
 
39
44
  def format_github_event(event, payload)
@@ -202,6 +207,22 @@ module CollavreGithub
202
207
  I18n.t("collavre_github.webhooks.#{key}", **options)
203
208
  end
204
209
 
210
+ def trigger_markdown_sync_for(link, event, payload)
211
+ return unless event == "push"
212
+
213
+ CollavreGithub::MarkdownSyncJob.perform_later(
214
+ link.id,
215
+ payload.as_json
216
+ )
217
+ end
218
+
219
+ def all_repository_links_for(payload)
220
+ repo = payload&.dig("repository", "full_name") || payload&.dig(:repository, :full_name)
221
+ return [ @repository_link ].compact if repo.blank?
222
+
223
+ CollavreGithub::RepositoryLink.where(repository_full_name: repo).to_a
224
+ end
225
+
205
226
  def find_repository_link(payload)
206
227
  if payload.blank?
207
228
  Rails.logger.warn("[GitHub Webhook] Payload is blank")