diff --git a/notifications/Makefile b/notifications/Makefile index 617967908..150124be0 100644 --- a/notifications/Makefile +++ b/notifications/Makefile @@ -4,7 +4,7 @@ include ../Makefile APP_NAME=$(shell grep 'app:' mix.exs | cut -d ':' -f3 | cut -d ',' -f1) PROTOC_TAG=1.12.1-3.17.3-0.7.1 -TMP_REPO_DIR=/tmp/internal_api +TMP_REPO_DIR ?= /tmp/internal_api INTERNAL_API_BRANCH ?= master PUBLIC_API_BRANCH ?= master diff --git a/notifications/lib/internal_api/notifications.pb.ex b/notifications/lib/internal_api/notifications.pb.ex index d170b1d98..e6fcfcee9 100644 --- a/notifications/lib/internal_api/notifications.pb.ex +++ b/notifications/lib/internal_api/notifications.pb.ex @@ -65,10 +65,11 @@ defmodule InternalApi.Notifications.Notification.Rule.Filter do pipelines: [String.t()], blocks: [String.t()], states: [[InternalApi.Notifications.Notification.Rule.Filter.State.t()]], - results: [[InternalApi.Notifications.Notification.Rule.Filter.Results.t()]] + results: [[InternalApi.Notifications.Notification.Rule.Filter.Results.t()]], + tags: [String.t()] } - defstruct [:projects, :branches, :pipelines, :blocks, :states, :results] + defstruct [:projects, :branches, :pipelines, :blocks, :states, :results, :tags] field(:projects, 1, repeated: true, type: :string) field(:branches, 2, repeated: true, type: :string) @@ -86,6 +87,8 @@ defmodule InternalApi.Notifications.Notification.Rule.Filter do type: InternalApi.Notifications.Notification.Rule.Filter.Results, enum: true ) + + field(:tags, 7, repeated: true, type: :string) end defmodule InternalApi.Notifications.Notification.Rule.Notify.Slack do @@ -224,10 +227,11 @@ defmodule InternalApi.Notifications.Notification do update_time: Google.Protobuf.Timestamp.t() | nil, rules: [InternalApi.Notifications.Notification.Rule.t()], status: InternalApi.Notifications.Notification.Status.t() | nil, - org_id: String.t() + org_id: String.t(), + creator_id: String.t() } - defstruct [:name, :id, :create_time, :update_time, :rules, :status, :org_id] + defstruct [:name, :id, :create_time, :update_time, :rules, :status, :org_id, :creator_id] field(:name, 1, type: :string) field(:id, 2, type: :string) @@ -236,6 +240,7 @@ defmodule InternalApi.Notifications.Notification do field(:rules, 5, repeated: true, type: InternalApi.Notifications.Notification.Rule) field(:status, 6, type: InternalApi.Notifications.Notification.Status) field(:org_id, 7, type: :string) + field(:creator_id, 8, type: :string) end defmodule InternalApi.Notifications.ListRequest do diff --git a/notifications/lib/internal_api/organization.pb.ex b/notifications/lib/internal_api/organization.pb.ex index 3d267f763..158ec3b1d 100644 --- a/notifications/lib/internal_api/organization.pb.ex +++ b/notifications/lib/internal_api/organization.pb.ex @@ -32,38 +32,6 @@ defmodule InternalApi.Organization.Member.Role do field(:ADMIN, 2) end -defmodule InternalApi.Organization.Quota.Type do - @moduledoc false - use Protobuf, enum: true, syntax: :proto3 - - @type t :: - integer - | :MAX_PEOPLE_IN_ORG - | :MAX_PARALELLISM_IN_ORG - | :MAX_PROJECTS_IN_ORG - | :MAX_PARALLEL_E1_STANDARD_2 - | :MAX_PARALLEL_E1_STANDARD_4 - | :MAX_PARALLEL_E1_STANDARD_8 - | :MAX_PARALLEL_A1_STANDARD_4 - | :MAX_PARALLEL_A1_STANDARD_8 - - field(:MAX_PEOPLE_IN_ORG, 0) - - field(:MAX_PARALELLISM_IN_ORG, 1) - - field(:MAX_PROJECTS_IN_ORG, 7) - - field(:MAX_PARALLEL_E1_STANDARD_2, 2) - - field(:MAX_PARALLEL_E1_STANDARD_4, 3) - - field(:MAX_PARALLEL_E1_STANDARD_8, 4) - - field(:MAX_PARALLEL_A1_STANDARD_4, 5) - - field(:MAX_PARALLEL_A1_STANDARD_8, 6) -end - defmodule InternalApi.Organization.OrganizationContact.ContactType do @moduledoc false use Protobuf, enum: true, syntax: :proto3 @@ -91,14 +59,16 @@ defmodule InternalApi.Organization.DescribeRequest do @type t :: %__MODULE__{ org_id: String.t(), org_username: String.t(), - include_quotas: boolean + include_quotas: boolean, + soft_deleted: boolean } - defstruct [:org_id, :org_username, :include_quotas] + defstruct [:org_id, :org_username, :include_quotas, :soft_deleted] field(:org_id, 1, type: :string) field(:org_username, 2, type: :string) field(:include_quotas, 3, type: :bool) + field(:soft_deleted, 4, type: :bool) end defmodule InternalApi.Organization.DescribeResponse do @@ -121,12 +91,14 @@ defmodule InternalApi.Organization.DescribeManyRequest do use Protobuf, syntax: :proto3 @type t :: %__MODULE__{ - org_ids: [String.t()] + org_ids: [String.t()], + soft_deleted: boolean } - defstruct [:org_ids] + defstruct [:org_ids, :soft_deleted] field(:org_ids, 1, repeated: true, type: :string) + field(:soft_deleted, 2, type: :bool) end defmodule InternalApi.Organization.DescribeManyResponse do @@ -151,16 +123,18 @@ defmodule InternalApi.Organization.ListRequest do created_at_gt: Google.Protobuf.Timestamp.t() | nil, order: InternalApi.Organization.ListRequest.Order.t(), page_size: integer, - page_token: String.t() + page_token: String.t(), + soft_deleted: boolean } - defstruct [:user_id, :created_at_gt, :order, :page_size, :page_token] + defstruct [:user_id, :created_at_gt, :order, :page_size, :page_token, :soft_deleted] field(:user_id, 2, type: :string) field(:created_at_gt, 3, type: Google.Protobuf.Timestamp) field(:order, 4, type: InternalApi.Organization.ListRequest.Order, enum: true) field(:page_size, 5, type: :int32) field(:page_token, 6, type: :string) + field(:soft_deleted, 7, type: :bool) end defmodule InternalApi.Organization.ListResponse do @@ -212,34 +186,6 @@ defmodule InternalApi.Organization.CreateResponse do field(:organization, 2, type: InternalApi.Organization.Organization) end -defmodule InternalApi.Organization.CreateWithQuotasRequest do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - organization: InternalApi.Organization.Organization.t() | nil, - quotas: [InternalApi.Organization.Quota.t()] - } - - defstruct [:organization, :quotas] - - field(:organization, 1, type: InternalApi.Organization.Organization) - field(:quotas, 2, repeated: true, type: InternalApi.Organization.Quota) -end - -defmodule InternalApi.Organization.CreateWithQuotasResponse do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - organization: InternalApi.Organization.Organization.t() | nil - } - - defstruct [:organization] - - field(:organization, 1, type: InternalApi.Organization.Organization) -end - defmodule InternalApi.Organization.UpdateRequest do @moduledoc false use Protobuf, syntax: :proto3 @@ -653,6 +599,19 @@ defmodule InternalApi.Organization.DestroyRequest do field(:org_id, 1, type: :string) end +defmodule InternalApi.Organization.RestoreRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t() + } + + defstruct [:org_id] + + field(:org_id, 1, type: :string) +end + defmodule InternalApi.Organization.Organization do @moduledoc false use Protobuf, syntax: :proto3 @@ -672,7 +631,6 @@ defmodule InternalApi.Organization.Organization do allowed_id_providers: [String.t()], deny_member_workflows: boolean, deny_non_member_workflows: boolean, - quotas: [InternalApi.Organization.Quota.t()], settings: [InternalApi.Organization.OrganizationSetting.t()] } @@ -691,7 +649,6 @@ defmodule InternalApi.Organization.Organization do :allowed_id_providers, :deny_member_workflows, :deny_non_member_workflows, - :quotas, :settings ] @@ -709,7 +666,6 @@ defmodule InternalApi.Organization.Organization do field(:allowed_id_providers, 13, repeated: true, type: :string) field(:deny_member_workflows, 14, type: :bool) field(:deny_non_member_workflows, 15, type: :bool) - field(:quotas, 8, repeated: true, type: InternalApi.Organization.Quota) field(:settings, 16, repeated: true, type: InternalApi.Organization.OrganizationSetting) end @@ -768,21 +724,6 @@ defmodule InternalApi.Organization.Member do field(:github_uid, 8, type: :string) end -defmodule InternalApi.Organization.Quota do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - type: InternalApi.Organization.Quota.Type.t(), - value: non_neg_integer - } - - defstruct [:type, :value] - - field(:type, 1, type: InternalApi.Organization.Quota.Type, enum: true) - field(:value, 2, type: :uint32) -end - defmodule InternalApi.Organization.OrganizationSetting do @moduledoc false use Protobuf, syntax: :proto3 @@ -798,62 +739,6 @@ defmodule InternalApi.Organization.OrganizationSetting do field(:value, 2, type: :string) end -defmodule InternalApi.Organization.GetQuotasRequest do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - org_id: String.t(), - types: [[InternalApi.Organization.Quota.Type.t()]] - } - - defstruct [:org_id, :types] - - field(:org_id, 1, type: :string) - field(:types, 2, repeated: true, type: InternalApi.Organization.Quota.Type, enum: true) -end - -defmodule InternalApi.Organization.GetQuotaResponse do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - quotas: [InternalApi.Organization.Quota.t()] - } - - defstruct [:quotas] - - field(:quotas, 1, repeated: true, type: InternalApi.Organization.Quota) -end - -defmodule InternalApi.Organization.UpdateQuotasRequest do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - org_id: String.t(), - quotas: [InternalApi.Organization.Quota.t()] - } - - defstruct [:org_id, :quotas] - - field(:org_id, 1, type: :string) - field(:quotas, 2, repeated: true, type: InternalApi.Organization.Quota) -end - -defmodule InternalApi.Organization.UpdateQuotasResponse do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - quotas: [InternalApi.Organization.Quota.t()] - } - - defstruct [:quotas] - - field(:quotas, 1, repeated: true, type: InternalApi.Organization.Quota) -end - defmodule InternalApi.Organization.RepositoryIntegratorsRequest do @moduledoc false use Protobuf, syntax: :proto3 @@ -1172,6 +1057,21 @@ defmodule InternalApi.Organization.OrganizationDailyUpdate do field(:timestamp, 11, type: Google.Protobuf.Timestamp) end +defmodule InternalApi.Organization.OrganizationRestored do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + timestamp: Google.Protobuf.Timestamp.t() | nil + } + + defstruct [:org_id, :timestamp] + + field(:org_id, 1, type: :string) + field(:timestamp, 2, type: Google.Protobuf.Timestamp) +end + defmodule InternalApi.Organization.OrganizationService.Service do @moduledoc false use GRPC.Service, name: "InternalApi.Organization.OrganizationService" @@ -1192,12 +1092,6 @@ defmodule InternalApi.Organization.OrganizationService.Service do rpc(:Create, InternalApi.Organization.CreateRequest, InternalApi.Organization.CreateResponse) - rpc( - :CreateWithQuotas, - InternalApi.Organization.CreateWithQuotasRequest, - InternalApi.Organization.CreateWithQuotasResponse - ) - rpc(:Update, InternalApi.Organization.UpdateRequest, InternalApi.Organization.UpdateResponse) rpc(:IsValid, InternalApi.Organization.Organization, InternalApi.Organization.IsValidResponse) @@ -1254,20 +1148,10 @@ defmodule InternalApi.Organization.OrganizationService.Service do InternalApi.Organization.ListSuspensionsResponse ) - rpc( - :UpdateQuotas, - InternalApi.Organization.UpdateQuotasRequest, - InternalApi.Organization.UpdateQuotasResponse - ) - - rpc( - :GetQuotas, - InternalApi.Organization.GetQuotasRequest, - InternalApi.Organization.GetQuotaResponse - ) - rpc(:Destroy, InternalApi.Organization.DestroyRequest, Google.Protobuf.Empty) + rpc(:Restore, InternalApi.Organization.RestoreRequest, Google.Protobuf.Empty) + rpc( :RepositoryIntegrators, InternalApi.Organization.RepositoryIntegratorsRequest, diff --git a/notifications/lib/internal_api/plumber.pipeline.pb.ex b/notifications/lib/internal_api/plumber.pipeline.pb.ex index 570094792..160474bc5 100644 --- a/notifications/lib/internal_api/plumber.pipeline.pb.ex +++ b/notifications/lib/internal_api/plumber.pipeline.pb.ex @@ -680,7 +680,9 @@ defmodule InternalApi.Plumber.ListKeysetRequest do done_after: Google.Protobuf.Timestamp.t() | nil, label: String.t(), git_ref_types: [[InternalApi.Plumber.GitRefType.t()]], - queue_id: String.t() + queue_id: String.t(), + pr_head_branch: String.t(), + pr_target_branch: String.t() } defstruct [ @@ -697,7 +699,9 @@ defmodule InternalApi.Plumber.ListKeysetRequest do :done_after, :label, :git_ref_types, - :queue_id + :queue_id, + :pr_head_branch, + :pr_target_branch ] field(:page_size, 1, type: :int32) @@ -714,6 +718,8 @@ defmodule InternalApi.Plumber.ListKeysetRequest do field(:label, 12, type: :string) field(:git_ref_types, 13, repeated: true, type: InternalApi.Plumber.GitRefType, enum: true) field(:queue_id, 14, type: :string) + field(:pr_head_branch, 15, type: :string) + field(:pr_target_branch, 16, type: :string) end defmodule InternalApi.Plumber.ListKeysetResponse do @@ -750,7 +756,9 @@ defmodule InternalApi.Plumber.ListRequest do done_after: Google.Protobuf.Timestamp.t() | nil, label: String.t(), git_ref_types: [[InternalApi.Plumber.GitRefType.t()]], - queue_id: String.t() + queue_id: String.t(), + pr_head_branch: String.t(), + pr_target_branch: String.t() } defstruct [ @@ -766,7 +774,9 @@ defmodule InternalApi.Plumber.ListRequest do :done_after, :label, :git_ref_types, - :queue_id + :queue_id, + :pr_head_branch, + :pr_target_branch ] field(:project_id, 1, type: :string) @@ -782,6 +792,8 @@ defmodule InternalApi.Plumber.ListRequest do field(:label, 11, type: :string) field(:git_ref_types, 12, repeated: true, type: InternalApi.Plumber.GitRefType, enum: true) field(:queue_id, 13, type: :string) + field(:pr_head_branch, 14, type: :string) + field(:pr_target_branch, 15, type: :string) end defmodule InternalApi.Plumber.ListResponse do @@ -869,7 +881,8 @@ defmodule InternalApi.Plumber.Pipeline do after_task_id: String.t(), repository_id: String.t(), env_vars: [InternalApi.Plumber.EnvVariable.t()], - triggerer: InternalApi.Plumber.Triggerer.t() | nil + triggerer: InternalApi.Plumber.Triggerer.t() | nil, + organization_id: String.t() } defstruct [ @@ -907,7 +920,8 @@ defmodule InternalApi.Plumber.Pipeline do :after_task_id, :repository_id, :env_vars, - :triggerer + :triggerer, + :organization_id ] field(:ppl_id, 1, type: :string) @@ -945,6 +959,7 @@ defmodule InternalApi.Plumber.Pipeline do field(:repository_id, 33, type: :string) field(:env_vars, 34, repeated: true, type: InternalApi.Plumber.EnvVariable) field(:triggerer, 35, type: InternalApi.Plumber.Triggerer) + field(:organization_id, 36, type: :string) end defmodule InternalApi.Plumber.Triggerer do diff --git a/notifications/lib/internal_api/plumber_w_f.workflow.pb.ex b/notifications/lib/internal_api/plumber_w_f.workflow.pb.ex index 2fc654a2d..d9977e404 100644 --- a/notifications/lib/internal_api/plumber_w_f.workflow.pb.ex +++ b/notifications/lib/internal_api/plumber_w_f.workflow.pb.ex @@ -27,7 +27,7 @@ end defmodule InternalApi.PlumberWF.ScheduleRequest.ServiceType do @moduledoc false use Protobuf, enum: true, syntax: :proto3 - @type t :: integer | :GIT_HUB | :LOCAL | :SNAPSHOT | :BITBUCKET + @type t :: integer | :GIT_HUB | :LOCAL | :SNAPSHOT | :BITBUCKET | :GITLAB | :GIT field(:GIT_HUB, 0) @@ -36,6 +36,10 @@ defmodule InternalApi.PlumberWF.ScheduleRequest.ServiceType do field(:SNAPSHOT, 2) field(:BITBUCKET, 3) + + field(:GITLAB, 4) + + field(:GIT, 5) end defmodule InternalApi.PlumberWF.ListLatestWorkflowsRequest.Order do @@ -158,7 +162,9 @@ defmodule InternalApi.PlumberWF.ScheduleRequest do label: String.t(), triggered_by: InternalApi.PlumberWF.TriggeredBy.t(), scheduler_task_id: String.t(), - env_vars: [InternalApi.PlumberWF.ScheduleRequest.EnvVar.t()] + env_vars: [InternalApi.PlumberWF.ScheduleRequest.EnvVar.t()], + start_in_conceived_state: boolean, + git_reference: String.t() } defstruct [ @@ -175,7 +181,9 @@ defmodule InternalApi.PlumberWF.ScheduleRequest do :label, :triggered_by, :scheduler_task_id, - :env_vars + :env_vars, + :start_in_conceived_state, + :git_reference ] field(:service, 2, type: InternalApi.PlumberWF.ScheduleRequest.ServiceType, enum: true) @@ -192,6 +200,8 @@ defmodule InternalApi.PlumberWF.ScheduleRequest do field(:triggered_by, 15, type: InternalApi.PlumberWF.TriggeredBy, enum: true) field(:scheduler_task_id, 16, type: :string) field(:env_vars, 17, repeated: true, type: InternalApi.PlumberWF.ScheduleRequest.EnvVar) + field(:start_in_conceived_state, 18, type: :bool) + field(:git_reference, 19, type: :string) end defmodule InternalApi.PlumberWF.ScheduleResponse do diff --git a/notifications/lib/internal_api/projecthub.pb.ex b/notifications/lib/internal_api/projecthub.pb.ex index 504a0401a..1462fa04d 100644 --- a/notifications/lib/internal_api/projecthub.pb.ex +++ b/notifications/lib/internal_api/projecthub.pb.ex @@ -49,7 +49,14 @@ end defmodule InternalApi.Projecthub.Project.Spec.Repository.RunType do @moduledoc false use Protobuf, enum: true, syntax: :proto3 - @type t :: integer | :BRANCHES | :TAGS | :PULL_REQUESTS | :FORKED_PULL_REQUESTS + + @type t :: + integer + | :BRANCHES + | :TAGS + | :PULL_REQUESTS + | :FORKED_PULL_REQUESTS + | :DRAFT_PULL_REQUESTS field(:BRANCHES, 0) @@ -58,6 +65,8 @@ defmodule InternalApi.Projecthub.Project.Spec.Repository.RunType do field(:PULL_REQUESTS, 2) field(:FORKED_PULL_REQUESTS, 3) + + field(:DRAFT_PULL_REQUESTS, 4) end defmodule InternalApi.Projecthub.Project.Spec.Repository.Status.PipelineFile.Level do @@ -97,13 +106,15 @@ end defmodule InternalApi.Projecthub.Project.Status.State do @moduledoc false use Protobuf, enum: true, syntax: :proto3 - @type t :: integer | :INITIALIZING | :READY | :ERROR + @type t :: integer | :INITIALIZING | :READY | :ERROR | :ONBOARDING field(:INITIALIZING, 0) field(:READY, 1) field(:ERROR, 2) + + field(:ONBOARDING, 3) end defmodule InternalApi.Projecthub.ListKeysetRequest.Direction do @@ -619,15 +630,17 @@ defmodule InternalApi.Projecthub.ListRequest do metadata: InternalApi.Projecthub.RequestMeta.t() | nil, pagination: InternalApi.Projecthub.PaginationRequest.t() | nil, owner_id: String.t(), - repo_url: String.t() + repo_url: String.t(), + soft_deleted: boolean } - defstruct [:metadata, :pagination, :owner_id, :repo_url] + defstruct [:metadata, :pagination, :owner_id, :repo_url, :soft_deleted] field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) field(:pagination, 2, type: InternalApi.Projecthub.PaginationRequest) field(:owner_id, 3, type: :string) field(:repo_url, 4, type: :string) + field(:soft_deleted, 5, type: :bool) end defmodule InternalApi.Projecthub.ListResponse do @@ -657,10 +670,11 @@ defmodule InternalApi.Projecthub.ListKeysetRequest do page_token: String.t(), direction: InternalApi.Projecthub.ListKeysetRequest.Direction.t(), owner_id: String.t(), - repo_url: String.t() + repo_url: String.t(), + created_after: Google.Protobuf.Timestamp.t() | nil } - defstruct [:metadata, :page_size, :page_token, :direction, :owner_id, :repo_url] + defstruct [:metadata, :page_size, :page_token, :direction, :owner_id, :repo_url, :created_after] field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) field(:page_size, 2, type: :int32) @@ -668,6 +682,7 @@ defmodule InternalApi.Projecthub.ListKeysetRequest do field(:direction, 4, type: InternalApi.Projecthub.ListKeysetRequest.Direction, enum: true) field(:owner_id, 5, type: :string) field(:repo_url, 6, type: :string) + field(:created_after, 7, type: Google.Protobuf.Timestamp) end defmodule InternalApi.Projecthub.ListKeysetResponse do @@ -697,15 +712,17 @@ defmodule InternalApi.Projecthub.DescribeRequest do metadata: InternalApi.Projecthub.RequestMeta.t() | nil, id: String.t(), name: String.t(), - detailed: boolean + detailed: boolean, + soft_deleted: boolean } - defstruct [:metadata, :id, :name, :detailed] + defstruct [:metadata, :id, :name, :detailed, :soft_deleted] field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) field(:id, 2, type: :string) field(:name, 3, type: :string) field(:detailed, 4, type: :bool) + field(:soft_deleted, 5, type: :bool) end defmodule InternalApi.Projecthub.DescribeResponse do @@ -729,13 +746,15 @@ defmodule InternalApi.Projecthub.DescribeManyRequest do @type t :: %__MODULE__{ metadata: InternalApi.Projecthub.RequestMeta.t() | nil, - ids: [String.t()] + ids: [String.t()], + soft_deleted: boolean } - defstruct [:metadata, :ids] + defstruct [:metadata, :ids, :soft_deleted] field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) field(:ids, 2, repeated: true, type: :string) + field(:soft_deleted, 3, type: :bool) end defmodule InternalApi.Projecthub.DescribeManyResponse do @@ -759,13 +778,15 @@ defmodule InternalApi.Projecthub.CreateRequest do @type t :: %__MODULE__{ metadata: InternalApi.Projecthub.RequestMeta.t() | nil, - project: InternalApi.Projecthub.Project.t() | nil + project: InternalApi.Projecthub.Project.t() | nil, + skip_onboarding: boolean } - defstruct [:metadata, :project] + defstruct [:metadata, :project, :skip_onboarding] field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) field(:project, 2, type: InternalApi.Projecthub.Project) + field(:skip_onboarding, 3, type: :bool) end defmodule InternalApi.Projecthub.CreateResponse do @@ -845,6 +866,34 @@ defmodule InternalApi.Projecthub.DestroyResponse do field(:metadata, 1, type: InternalApi.Projecthub.ResponseMeta) end +defmodule InternalApi.Projecthub.RestoreRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + metadata: InternalApi.Projecthub.RequestMeta.t() | nil, + id: String.t() + } + + defstruct [:metadata, :id] + + field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) + field(:id, 2, type: :string) +end + +defmodule InternalApi.Projecthub.RestoreResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + metadata: InternalApi.Projecthub.ResponseMeta.t() | nil + } + + defstruct [:metadata] + + field(:metadata, 1, type: InternalApi.Projecthub.ResponseMeta) +end + defmodule InternalApi.Projecthub.UsersRequest do @moduledoc false use Protobuf, syntax: :proto3 @@ -897,14 +946,16 @@ defmodule InternalApi.Projecthub.CheckDeployKeyResponse.DeployKey do @type t :: %__MODULE__{ title: String.t(), fingerprint: String.t(), - created_at: Google.Protobuf.Timestamp.t() | nil + created_at: Google.Protobuf.Timestamp.t() | nil, + public_key: String.t() } - defstruct [:title, :fingerprint, :created_at] + defstruct [:title, :fingerprint, :created_at, :public_key] field(:title, 1, type: :string) field(:fingerprint, 2, type: :string) field(:created_at, 3, type: Google.Protobuf.Timestamp) + field(:public_key, 4, type: :string) end defmodule InternalApi.Projecthub.CheckDeployKeyResponse do @@ -944,14 +995,16 @@ defmodule InternalApi.Projecthub.RegenerateDeployKeyResponse.DeployKey do @type t :: %__MODULE__{ title: String.t(), fingerprint: String.t(), - created_at: Google.Protobuf.Timestamp.t() | nil + created_at: Google.Protobuf.Timestamp.t() | nil, + public_key: String.t() } - defstruct [:title, :fingerprint, :created_at] + defstruct [:title, :fingerprint, :created_at, :public_key] field(:title, 1, type: :string) field(:fingerprint, 2, type: :string) field(:created_at, 3, type: Google.Protobuf.Timestamp) + field(:public_key, 4, type: :string) end defmodule InternalApi.Projecthub.RegenerateDeployKeyResponse do @@ -1130,6 +1183,64 @@ defmodule InternalApi.Projecthub.GithubAppSwitchResponse do field(:metadata, 1, type: InternalApi.Projecthub.ResponseMeta) end +defmodule InternalApi.Projecthub.FinishOnboardingRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + metadata: InternalApi.Projecthub.RequestMeta.t() | nil, + id: String.t() + } + + defstruct [:metadata, :id] + + field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) + field(:id, 2, type: :string) +end + +defmodule InternalApi.Projecthub.FinishOnboardingResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + metadata: InternalApi.Projecthub.ResponseMeta.t() | nil + } + + defstruct [:metadata] + + field(:metadata, 1, type: InternalApi.Projecthub.ResponseMeta) +end + +defmodule InternalApi.Projecthub.RegenerateWebhookSecretRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + metadata: InternalApi.Projecthub.RequestMeta.t() | nil, + id: String.t() + } + + defstruct [:metadata, :id] + + field(:metadata, 1, type: InternalApi.Projecthub.RequestMeta) + field(:id, 2, type: :string) +end + +defmodule InternalApi.Projecthub.RegenerateWebhookSecretResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + metadata: InternalApi.Projecthub.ResponseMeta.t() | nil, + secret: String.t() + } + + defstruct [:metadata, :secret] + + field(:metadata, 1, type: InternalApi.Projecthub.ResponseMeta) + field(:secret, 2, type: :string) +end + defmodule InternalApi.Projecthub.ProjectCreated do @moduledoc false use Protobuf, syntax: :proto3 @@ -1164,6 +1275,23 @@ defmodule InternalApi.Projecthub.ProjectDeleted do field(:org_id, 3, type: :string) end +defmodule InternalApi.Projecthub.ProjectRestored do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + project_id: String.t(), + timestamp: Google.Protobuf.Timestamp.t() | nil, + org_id: String.t() + } + + defstruct [:project_id, :timestamp, :org_id] + + field(:project_id, 1, type: :string) + field(:timestamp, 2, type: Google.Protobuf.Timestamp) + field(:org_id, 3, type: :string) +end + defmodule InternalApi.Projecthub.ProjectUpdated do @moduledoc false use Protobuf, syntax: :proto3 @@ -1222,6 +1350,8 @@ defmodule InternalApi.Projecthub.ProjectService.Service do rpc(:Destroy, InternalApi.Projecthub.DestroyRequest, InternalApi.Projecthub.DestroyResponse) + rpc(:Restore, InternalApi.Projecthub.RestoreRequest, InternalApi.Projecthub.RestoreResponse) + rpc(:Users, InternalApi.Projecthub.UsersRequest, InternalApi.Projecthub.UsersResponse) rpc( @@ -1248,6 +1378,12 @@ defmodule InternalApi.Projecthub.ProjectService.Service do InternalApi.Projecthub.RegenerateWebhookResponse ) + rpc( + :RegenerateWebhookSecret, + InternalApi.Projecthub.RegenerateWebhookSecretRequest, + InternalApi.Projecthub.RegenerateWebhookSecretResponse + ) + rpc( :ChangeProjectOwner, InternalApi.Projecthub.ChangeProjectOwnerRequest, @@ -1265,6 +1401,12 @@ defmodule InternalApi.Projecthub.ProjectService.Service do InternalApi.Projecthub.GithubAppSwitchRequest, InternalApi.Projecthub.GithubAppSwitchResponse ) + + rpc( + :FinishOnboarding, + InternalApi.Projecthub.FinishOnboardingRequest, + InternalApi.Projecthub.FinishOnboardingResponse + ) end defmodule InternalApi.Projecthub.ProjectService.Stub do diff --git a/notifications/lib/internal_api/rbac.pb.ex b/notifications/lib/internal_api/rbac.pb.ex index 0606c55f5..7fc28e841 100644 --- a/notifications/lib/internal_api/rbac.pb.ex +++ b/notifications/lib/internal_api/rbac.pb.ex @@ -1,11 +1,13 @@ defmodule InternalApi.RBAC.SubjectType do @moduledoc false use Protobuf, enum: true, syntax: :proto3 - @type t :: integer | :USER | :GROUP + @type t :: integer | :USER | :GROUP | :SERVICE_ACCOUNT field(:USER, 0) field(:GROUP, 1) + + field(:SERVICE_ACCOUNT, 2) end defmodule InternalApi.RBAC.Scope do @@ -33,6 +35,7 @@ defmodule InternalApi.RBAC.RoleBindingSource do | :ROLE_BINDING_SOURCE_GITLAB | :ROLE_BINDING_SOURCE_SCIM | :ROLE_BINDING_SOURCE_INHERITED_FROM_ORG_ROLE + | :ROLE_BINDING_SOURCE_SAML_JIT field(:ROLE_BINDING_SOURCE_UNSPECIFIED, 0) @@ -47,6 +50,8 @@ defmodule InternalApi.RBAC.RoleBindingSource do field(:ROLE_BINDING_SOURCE_SCIM, 5) field(:ROLE_BINDING_SOURCE_INHERITED_FROM_ORG_ROLE, 6) + + field(:ROLE_BINDING_SOURCE_SAML_JIT, 7) end defmodule InternalApi.RBAC.ListUserPermissionsRequest do @@ -226,6 +231,92 @@ defmodule InternalApi.RBAC.ListRolesResponse do field(:roles, 1, repeated: true, type: InternalApi.RBAC.Role) end +defmodule InternalApi.RBAC.DescribeRoleRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + role_id: String.t() + } + + defstruct [:org_id, :role_id] + + field(:org_id, 1, type: :string) + field(:role_id, 2, type: :string) +end + +defmodule InternalApi.RBAC.DescribeRoleResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + role: InternalApi.RBAC.Role.t() | nil + } + + defstruct [:role] + + field(:role, 1, type: InternalApi.RBAC.Role) +end + +defmodule InternalApi.RBAC.ModifyRoleRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + role: InternalApi.RBAC.Role.t() | nil, + requester_id: String.t() + } + + defstruct [:role, :requester_id] + + field(:role, 1, type: InternalApi.RBAC.Role) + field(:requester_id, 2, type: :string) +end + +defmodule InternalApi.RBAC.ModifyRoleResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + role: InternalApi.RBAC.Role.t() | nil + } + + defstruct [:role] + + field(:role, 1, type: InternalApi.RBAC.Role) +end + +defmodule InternalApi.RBAC.DestroyRoleRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + role_id: String.t(), + requester_id: String.t() + } + + defstruct [:org_id, :role_id, :requester_id] + + field(:org_id, 1, type: :string) + field(:role_id, 2, type: :string) + field(:requester_id, 3, type: :string) +end + +defmodule InternalApi.RBAC.DestroyRoleResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + role_id: String.t() + } + + defstruct [:role_id] + + field(:role_id, 1, type: :string) +end + defmodule InternalApi.RBAC.ListMembersRequest.Page do @moduledoc false use Protobuf, syntax: :proto3 @@ -270,15 +361,13 @@ defmodule InternalApi.RBAC.ListMembersResponse.Member do @type t :: %__MODULE__{ subject: InternalApi.RBAC.Subject.t() | nil, - subject_role_bindings: [InternalApi.RBAC.SubjectRoleBinding.t()], - roles: [InternalApi.RBAC.Role.t()] + subject_role_bindings: [InternalApi.RBAC.SubjectRoleBinding.t()] } - defstruct [:subject, :subject_role_bindings, :roles] + defstruct [:subject, :subject_role_bindings] field(:subject, 1, type: InternalApi.RBAC.Subject) field(:subject_role_bindings, 3, repeated: true, type: InternalApi.RBAC.SubjectRoleBinding) - field(:roles, 2, repeated: true, type: InternalApi.RBAC.Role) end defmodule InternalApi.RBAC.ListMembersResponse do @@ -296,6 +385,32 @@ defmodule InternalApi.RBAC.ListMembersResponse do field(:total_pages, 2, type: :int32) end +defmodule InternalApi.RBAC.CountMembersRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t() + } + + defstruct [:org_id] + + field(:org_id, 1, type: :string) +end + +defmodule InternalApi.RBAC.CountMembersResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + members: integer + } + + defstruct [:members] + + field(:members, 1, type: :int32) +end + defmodule InternalApi.RBAC.SubjectRoleBinding do @moduledoc false use Protobuf, syntax: :proto3 @@ -403,6 +518,27 @@ defmodule InternalApi.RBAC.Subject do field(:display_name, 3, type: :string) end +defmodule InternalApi.RBAC.RefreshCollaboratorsRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t() + } + + defstruct [:org_id] + + field(:org_id, 1, type: :string) +end + +defmodule InternalApi.RBAC.RefreshCollaboratorsResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + @type t :: %__MODULE__{} + + defstruct [] +end + defmodule InternalApi.RBAC.Role do @moduledoc false use Protobuf, syntax: :proto3 @@ -416,7 +552,8 @@ defmodule InternalApi.RBAC.Role do permissions: [String.t()], rbac_permissions: [InternalApi.RBAC.Permission.t()], inherited_role: InternalApi.RBAC.Role.t() | nil, - maps_to: InternalApi.RBAC.Role.t() | nil + maps_to: InternalApi.RBAC.Role.t() | nil, + readonly: boolean } defstruct [ @@ -428,7 +565,8 @@ defmodule InternalApi.RBAC.Role do :permissions, :rbac_permissions, :inherited_role, - :maps_to + :maps_to, + :readonly ] field(:id, 1, type: :string) @@ -440,6 +578,7 @@ defmodule InternalApi.RBAC.Role do field(:rbac_permissions, 7, repeated: true, type: InternalApi.RBAC.Permission) field(:inherited_role, 8, type: InternalApi.RBAC.Role) field(:maps_to, 9, type: InternalApi.RBAC.Role) + field(:readonly, 10, type: :bool) end defmodule InternalApi.RBAC.Permission do @@ -489,8 +628,16 @@ defmodule InternalApi.RBAC.RBAC.Service do rpc(:ListRoles, InternalApi.RBAC.ListRolesRequest, InternalApi.RBAC.ListRolesResponse) + rpc(:DescribeRole, InternalApi.RBAC.DescribeRoleRequest, InternalApi.RBAC.DescribeRoleResponse) + + rpc(:ModifyRole, InternalApi.RBAC.ModifyRoleRequest, InternalApi.RBAC.ModifyRoleResponse) + + rpc(:DestroyRole, InternalApi.RBAC.DestroyRoleRequest, InternalApi.RBAC.DestroyRoleResponse) + rpc(:ListMembers, InternalApi.RBAC.ListMembersRequest, InternalApi.RBAC.ListMembersResponse) + rpc(:CountMembers, InternalApi.RBAC.CountMembersRequest, InternalApi.RBAC.CountMembersResponse) + rpc( :ListAccessibleOrgs, InternalApi.RBAC.ListAccessibleOrgsRequest, @@ -502,6 +649,12 @@ defmodule InternalApi.RBAC.RBAC.Service do InternalApi.RBAC.ListAccessibleProjectsRequest, InternalApi.RBAC.ListAccessibleProjectsResponse ) + + rpc( + :RefreshCollaborators, + InternalApi.RBAC.RefreshCollaboratorsRequest, + InternalApi.RBAC.RefreshCollaboratorsResponse + ) end defmodule InternalApi.RBAC.RBAC.Stub do diff --git a/notifications/lib/internal_api/repo_proxy.pb.ex b/notifications/lib/internal_api/repo_proxy.pb.ex index a7b7e8c36..929c6855c 100644 --- a/notifications/lib/internal_api/repo_proxy.pb.ex +++ b/notifications/lib/internal_api/repo_proxy.pb.ex @@ -357,6 +357,23 @@ defmodule InternalApi.RepoProxy.CreateBlankResponse do field(:repo, 5, type: InternalApi.RepoProxy.CreateBlankResponse.Repo) end +defmodule InternalApi.RepoProxy.PullRequestUnmergeable do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + project_id: String.t(), + branch_name: String.t(), + timestamp: Google.Protobuf.Timestamp.t() | nil + } + + defstruct [:project_id, :branch_name, :timestamp] + + field(:project_id, 1, type: :string) + field(:branch_name, 2, type: :string) + field(:timestamp, 3, type: Google.Protobuf.Timestamp) +end + defmodule InternalApi.RepoProxy.RepoProxyService.Service do @moduledoc false use GRPC.Service, name: "InternalApi.RepoProxy.RepoProxyService" diff --git a/notifications/lib/internal_api/repository_integrator.pb.ex b/notifications/lib/internal_api/repository_integrator.pb.ex index 57140eb2f..d16dc51b9 100644 --- a/notifications/lib/internal_api/repository_integrator.pb.ex +++ b/notifications/lib/internal_api/repository_integrator.pb.ex @@ -1,13 +1,17 @@ defmodule InternalApi.RepositoryIntegrator.IntegrationType do @moduledoc false use Protobuf, enum: true, syntax: :proto3 - @type t :: integer | :GITHUB_OAUTH_TOKEN | :GITHUB_APP | :BITBUCKET + @type t :: integer | :GITHUB_OAUTH_TOKEN | :GITHUB_APP | :BITBUCKET | :GITLAB | :GIT field(:GITHUB_OAUTH_TOKEN, 0) field(:GITHUB_APP, 1) field(:BITBUCKET, 2) + + field(:GITLAB, 3) + + field(:GIT, 4) end defmodule InternalApi.RepositoryIntegrator.IntegrationScope do @@ -162,6 +166,22 @@ defmodule InternalApi.RepositoryIntegrator.GithubInstallationInfoResponse do field(:installation_url, 3, type: :string) end +defmodule InternalApi.RepositoryIntegrator.InitGithubInstallationRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + @type t :: %__MODULE__{} + + defstruct [] +end + +defmodule InternalApi.RepositoryIntegrator.InitGithubInstallationResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + @type t :: %__MODULE__{} + + defstruct [] +end + defmodule InternalApi.RepositoryIntegrator.GetRepositoriesRequest do @moduledoc false use Protobuf, syntax: :proto3 @@ -245,6 +265,12 @@ defmodule InternalApi.RepositoryIntegrator.RepositoryIntegratorService.Service d InternalApi.RepositoryIntegrator.GithubInstallationInfoResponse ) + rpc( + :InitGithubInstallation, + InternalApi.RepositoryIntegrator.InitGithubInstallationRequest, + InternalApi.RepositoryIntegrator.InitGithubInstallationResponse + ) + rpc( :GetRepositories, InternalApi.RepositoryIntegrator.GetRepositoriesRequest, diff --git a/notifications/lib/internal_api/secrethub.pb.ex b/notifications/lib/internal_api/secrethub.pb.ex index bd82a45dd..24d0400cc 100644 --- a/notifications/lib/internal_api/secrethub.pb.ex +++ b/notifications/lib/internal_api/secrethub.pb.ex @@ -719,7 +719,10 @@ defmodule InternalApi.Secrethub.GenerateOpenIDConnectTokenRequest do git_pull_request_number: String.t(), org_username: String.t(), job_type: String.t(), - git_pull_request_branch: String.t() + git_pull_request_branch: String.t(), + repo_slug: String.t(), + triggerer: String.t(), + project_name: String.t() } defstruct [ @@ -739,7 +742,10 @@ defmodule InternalApi.Secrethub.GenerateOpenIDConnectTokenRequest do :git_pull_request_number, :org_username, :job_type, - :git_pull_request_branch + :git_pull_request_branch, + :repo_slug, + :triggerer, + :project_name ] field(:org_id, 1, type: :string) @@ -759,6 +765,9 @@ defmodule InternalApi.Secrethub.GenerateOpenIDConnectTokenRequest do field(:org_username, 15, type: :string) field(:job_type, 16, type: :string) field(:git_pull_request_branch, 17, type: :string) + field(:repo_slug, 18, type: :string) + field(:triggerer, 19, type: :string) + field(:project_name, 20, type: :string) end defmodule InternalApi.Secrethub.GenerateOpenIDConnectTokenResponse do @@ -865,6 +874,97 @@ defmodule InternalApi.Secrethub.UpdateEncryptedResponse do field(:encrypted_data, 3, type: InternalApi.Secrethub.EncryptedData) end +defmodule InternalApi.Secrethub.GetJWTConfigRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + project_id: String.t() + } + + defstruct [:org_id, :project_id] + + field(:org_id, 1, type: :string) + field(:project_id, 2, type: :string) +end + +defmodule InternalApi.Secrethub.GetJWTConfigResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + project_id: String.t(), + claims: [InternalApi.Secrethub.ClaimConfig.t()], + is_active: boolean + } + + defstruct [:org_id, :project_id, :claims, :is_active] + + field(:org_id, 1, type: :string) + field(:project_id, 2, type: :string) + field(:claims, 3, repeated: true, type: InternalApi.Secrethub.ClaimConfig) + field(:is_active, 4, type: :bool) +end + +defmodule InternalApi.Secrethub.UpdateJWTConfigRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + project_id: String.t(), + claims: [InternalApi.Secrethub.ClaimConfig.t()], + is_active: boolean + } + + defstruct [:org_id, :project_id, :claims, :is_active] + + field(:org_id, 1, type: :string) + field(:project_id, 2, type: :string) + field(:claims, 3, repeated: true, type: InternalApi.Secrethub.ClaimConfig) + field(:is_active, 4, type: :bool) +end + +defmodule InternalApi.Secrethub.UpdateJWTConfigResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + org_id: String.t(), + project_id: String.t() + } + + defstruct [:org_id, :project_id] + + field(:org_id, 1, type: :string) + field(:project_id, 2, type: :string) +end + +defmodule InternalApi.Secrethub.ClaimConfig do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + name: String.t(), + description: String.t(), + is_active: boolean, + is_mandatory: boolean, + is_aws_tag: boolean, + is_system_claim: boolean + } + + defstruct [:name, :description, :is_active, :is_mandatory, :is_aws_tag, :is_system_claim] + + field(:name, 1, type: :string) + field(:description, 2, type: :string) + field(:is_active, 3, type: :bool) + field(:is_mandatory, 4, type: :bool) + field(:is_aws_tag, 5, type: :bool) + field(:is_system_claim, 6, type: :bool) +end + defmodule InternalApi.Secrethub.SecretService.Service do @moduledoc false use GRPC.Service, name: "InternalApi.Secrethub.SecretService" @@ -918,6 +1018,18 @@ defmodule InternalApi.Secrethub.SecretService.Service do InternalApi.Secrethub.CheckoutManyRequest, InternalApi.Secrethub.CheckoutManyResponse ) + + rpc( + :GetJWTConfig, + InternalApi.Secrethub.GetJWTConfigRequest, + InternalApi.Secrethub.GetJWTConfigResponse + ) + + rpc( + :UpdateJWTConfig, + InternalApi.Secrethub.UpdateJWTConfigRequest, + InternalApi.Secrethub.UpdateJWTConfigResponse + ) end defmodule InternalApi.Secrethub.SecretService.Stub do diff --git a/notifications/lib/internal_api/user.pb.ex b/notifications/lib/internal_api/user.pb.ex index 0aea79f06..99840da16 100644 --- a/notifications/lib/internal_api/user.pb.ex +++ b/notifications/lib/internal_api/user.pb.ex @@ -63,11 +63,13 @@ end defmodule InternalApi.User.User.CreationSource do @moduledoc false use Protobuf, enum: true, syntax: :proto3 - @type t :: integer | :NOT_SET | :OKTA + @type t :: integer | :NOT_SET | :OKTA | :SERVICE_ACCOUNT field(:NOT_SET, 0) field(:OKTA, 1) + + field(:SERVICE_ACCOUNT, 2) end defmodule InternalApi.User.ListFavoritesRequest do @@ -363,36 +365,6 @@ defmodule InternalApi.User.RegenerateTokenResponse do field(:api_token, 3, type: :string) end -defmodule InternalApi.User.RefererRequest do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - user_id: String.t() - } - - defstruct [:user_id] - - field(:user_id, 1, type: :string) -end - -defmodule InternalApi.User.RefererResponse do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - user_id: String.t(), - entry_url: String.t(), - http_referer: String.t() - } - - defstruct [:user_id, :entry_url, :http_referer] - - field(:user_id, 1, type: :string) - field(:entry_url, 2, type: :string) - field(:http_referer, 3, type: :string) -end - defmodule InternalApi.User.CheckGithubTokenRequest do @moduledoc false use Protobuf, syntax: :proto3 @@ -492,6 +464,19 @@ defmodule InternalApi.User.DescribeByRepositoryProviderRequest do field(:provider, 1, type: InternalApi.User.RepositoryProvider) end +defmodule InternalApi.User.DescribeByEmailRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + email: String.t() + } + + defstruct [:email] + + field(:email, 1, type: :string) +end + defmodule InternalApi.User.RefreshRepositoryProviderRequest do @moduledoc false use Protobuf, syntax: :proto3 @@ -522,6 +507,27 @@ defmodule InternalApi.User.RefreshRepositoryProviderResponse do field(:repository_provider, 2, type: InternalApi.User.RepositoryProvider) end +defmodule InternalApi.User.CreateRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + email: String.t(), + name: String.t(), + password: String.t(), + repository_providers: [InternalApi.User.RepositoryProvider.t()], + skip_password_change: boolean + } + + defstruct [:email, :name, :password, :repository_providers, :skip_password_change] + + field(:email, 1, type: :string) + field(:name, 2, type: :string) + field(:password, 3, type: :string) + field(:repository_providers, 4, repeated: true, type: InternalApi.User.RepositoryProvider) + field(:skip_password_change, 5, type: :bool) +end + defmodule InternalApi.User.User do @moduledoc false use Protobuf, syntax: :proto3 @@ -626,23 +632,6 @@ defmodule InternalApi.User.UserUpdated do field(:timestamp, 2, type: Google.Protobuf.Timestamp) end -defmodule InternalApi.User.UserRefererCreated do - @moduledoc false - use Protobuf, syntax: :proto3 - - @type t :: %__MODULE__{ - user_id: String.t(), - entry_url: String.t(), - http_referer: String.t() - } - - defstruct [:user_id, :entry_url, :http_referer] - - field(:user_id, 1, type: :string) - field(:entry_url, 2, type: :string) - field(:http_referer, 3, type: :string) -end - defmodule InternalApi.User.UserJoinedOrganization do @moduledoc false use Protobuf, syntax: :proto3 @@ -785,6 +774,8 @@ defmodule InternalApi.User.UserService.Service do InternalApi.User.User ) + rpc(:DescribeByEmail, InternalApi.User.DescribeByEmailRequest, InternalApi.User.User) + rpc(:SearchUsers, InternalApi.User.SearchUsersRequest, InternalApi.User.SearchUsersResponse) rpc(:DescribeMany, InternalApi.User.DescribeManyRequest, InternalApi.User.DescribeManyResponse) @@ -809,8 +800,6 @@ defmodule InternalApi.User.UserService.Service do rpc(:DeleteFavorite, InternalApi.User.Favorite, InternalApi.User.Favorite) - rpc(:Referer, InternalApi.User.RefererRequest, InternalApi.User.RefererResponse) - rpc( :CheckGithubToken, InternalApi.User.CheckGithubTokenRequest, @@ -832,6 +821,8 @@ defmodule InternalApi.User.UserService.Service do InternalApi.User.RefreshRepositoryProviderRequest, InternalApi.User.RefreshRepositoryProviderResponse ) + + rpc(:Create, InternalApi.User.CreateRequest, InternalApi.User.User) end defmodule InternalApi.User.UserService.Stub do diff --git a/notifications/lib/notifications/util/rule_factory.ex b/notifications/lib/notifications/util/rule_factory.ex index 1fd4d2d42..b82d349c4 100644 --- a/notifications/lib/notifications/util/rule_factory.ex +++ b/notifications/lib/notifications/util/rule_factory.ex @@ -35,7 +35,8 @@ defmodule Notifications.Util.RuleFactory do Models.Pattern.new(org_id, r.id, rule.filter.branches, "branch") ++ Models.Pattern.new(org_id, r.id, rule.filter.pipelines, "pipeline") ++ Models.Pattern.new(org_id, r.id, rule.filter.blocks, "block") ++ - Models.Pattern.new(org_id, r.id, rule.filter.results, "result") + Models.Pattern.new(org_id, r.id, rule.filter.results, "result") ++ + Models.Pattern.new(org_id, r.id, rule.filter.tags, "tag") # create block rules if doesn't exists patterns = @@ -69,6 +70,14 @@ defmodule Notifications.Util.RuleFactory do patterns end + # create tag rules if don't exist + patterns = + if Map.get(rule.filter, :tags, []) == [] do + patterns ++ Models.Pattern.new(org_id, r.id, ["/.*/"], "tag") + else + patterns + end + Enum.map(patterns, fn p -> {:ok, _} = Repo.insert(p) end) diff --git a/notifications/lib/notifications/util/validator.ex b/notifications/lib/notifications/util/validator.ex index 8a088e688..34774e718 100644 --- a/notifications/lib/notifications/util/validator.ex +++ b/notifications/lib/notifications/util/validator.ex @@ -104,7 +104,8 @@ defmodule Notifications.Util.Validator do rule.filter.branches ++ rule.filter.pipelines ++ rule.filter.blocks ++ - rule.filter.results + rule.filter.results ++ + rule.filter.tags end) end diff --git a/notifications/lib/notifications/workers/coordinator.ex b/notifications/lib/notifications/workers/coordinator.ex index 3cdb0edf1..37ccbf58b 100644 --- a/notifications/lib/notifications/workers/coordinator.ex +++ b/notifications/lib/notifications/workers/coordinator.ex @@ -26,14 +26,19 @@ defmodule Notifications.Workers.Coordinator do Logger.info("#{request_id} #{event.pipeline_id} #{project.metadata.name}") + tag_name = if hook.git_ref_type == :TAG, do: hook.git_ref, else: nil + branch_name = if hook.git_ref_type == :TAG, do: nil, else: pipeline.branch_name + pr_branch_name = if hook.git_ref_type == :TAG, do: "", else: hook.pr_branch_name + rules = Filter.find_rules( project.metadata.org_id, project.metadata.name, - pipeline.branch_name, - hook.pr_branch_name, + branch_name, + pr_branch_name, pipeline.yaml_file_name, - map_result_to_string(pipeline.result) + map_result_to_string(pipeline.result), + tag_name ) Logger.info("#{request_id} #{event.pipeline_id} #{inspect(rules)}") diff --git a/notifications/lib/notifications/workers/coordinator/filter.ex b/notifications/lib/notifications/workers/coordinator/filter.ex index 2e3ab0187..e3529adec 100644 --- a/notifications/lib/notifications/workers/coordinator/filter.ex +++ b/notifications/lib/notifications/workers/coordinator/filter.ex @@ -3,13 +3,14 @@ defmodule Notifications.Workers.Coordinator.Filter do alias Notifications.Models.Rule alias Notifications.Repo - def find_rules(org_id, project, branch, pr_branch, pipeline, result) do + def find_rules(org_id, project, branch, pr_branch, pipeline, result, tag \\ nil) do Rule |> where([r], r.org_id == ^org_id) |> with_pattern(project, "project") |> with_pattern([branch, pr_branch], "branch") |> with_pattern(pipeline, "pipeline") |> with_pattern(result, "result") + |> with_pattern(tag, "tag") |> preload(:notification) |> Repo.all() end @@ -18,6 +19,10 @@ defmodule Notifications.Workers.Coordinator.Filter do with_pattern(query, actual_value, pattern_type) end + defp with_pattern(query, nil, _pattern_type) do + query + end + defp with_pattern(query, [actual_value1, actual_value2], pattern_type) do query |> where( diff --git a/notifications/lib/public_api/semaphore/notifications.v1alpha.pb.ex b/notifications/lib/public_api/semaphore/notifications.v1alpha.pb.ex index 65718dc97..5ddb18a27 100644 --- a/notifications/lib/public_api/semaphore/notifications.v1alpha.pb.ex +++ b/notifications/lib/public_api/semaphore/notifications.v1alpha.pb.ex @@ -57,10 +57,11 @@ defmodule Semaphore.Notifications.V1alpha.Notification.Spec.Rule.Filter do pipelines: [String.t()], blocks: [String.t()], states: [[Semaphore.Notifications.V1alpha.Notification.Spec.Rule.Filter.State.t()]], - results: [String.t()] + results: [String.t()], + tags: [String.t()] } - defstruct [:projects, :branches, :pipelines, :blocks, :states, :results] + defstruct [:projects, :branches, :pipelines, :blocks, :states, :results, :tags] field(:projects, 1, repeated: true, type: :string) field(:branches, 2, repeated: true, type: :string) @@ -74,6 +75,7 @@ defmodule Semaphore.Notifications.V1alpha.Notification.Spec.Rule.Filter do ) field(:results, 6, repeated: true, type: :string) + field(:tags, 7, repeated: true, type: :string) end defmodule Semaphore.Notifications.V1alpha.Notification.Spec.Rule.Notify.Slack do diff --git a/notifications/test/notifications/api/internal_api/create_test.exs b/notifications/test/notifications/api/internal_api/create_test.exs index 29bea8c11..c86519b1d 100644 --- a/notifications/test/notifications/api/internal_api/create_test.exs +++ b/notifications/test/notifications/api/internal_api/create_test.exs @@ -63,7 +63,7 @@ defmodule Notifications.Api.InternalApi.CreateTest do "secret" => "B7L2XRJ12" } - assert length(rule.patterns) == 8 + assert length(rule.patterns) == 9 assert Enum.find(rule.patterns, fn p -> p.type == "project" && p.regex && p.term == "^s2-*" diff --git a/notifications/test/notifications/api/internal_api/update_test.exs b/notifications/test/notifications/api/internal_api/update_test.exs index ec65615f7..fafc96310 100644 --- a/notifications/test/notifications/api/internal_api/update_test.exs +++ b/notifications/test/notifications/api/internal_api/update_test.exs @@ -91,7 +91,7 @@ defmodule Notifications.Api.InternalApi.UpdateTest do "secret" => "B7L2XRJ12" } - assert length(rule.patterns) == 8 + assert length(rule.patterns) == 9 assert Enum.find(rule.patterns, fn p -> p.type == "project" && p.regex && p.term == "^s2-*" diff --git a/notifications/test/notifications/api/public_api/create_test.exs b/notifications/test/notifications/api/public_api/create_test.exs index 6db196e91..8ec0b28a5 100644 --- a/notifications/test/notifications/api/public_api/create_test.exs +++ b/notifications/test/notifications/api/public_api/create_test.exs @@ -79,7 +79,7 @@ defmodule Notifications.Api.PublicApi.CreateTest do "secret" => "B7L2XRJ12" } - assert length(rule.patterns) == 8 + assert length(rule.patterns) == 9 assert Enum.find(rule.patterns, fn p -> p.type == "project" && p.regex && p.term == "^s2-*" diff --git a/notifications/test/notifications/api/public_api/update_test.exs b/notifications/test/notifications/api/public_api/update_test.exs index 320f5ee49..502b902a8 100644 --- a/notifications/test/notifications/api/public_api/update_test.exs +++ b/notifications/test/notifications/api/public_api/update_test.exs @@ -132,7 +132,7 @@ defmodule Notifications.Api.PublicApi.UpdateTest do "secret" => "B7L2XRJ12" } - assert length(rule.patterns) == 8 + assert length(rule.patterns) == 9 assert Enum.find(rule.patterns, fn p -> p.type == "project" && p.regex && p.term == "^s2-*" diff --git a/notifications/test/notifications/workers/coordinator/filter_test.exs b/notifications/test/notifications/workers/coordinator/filter_test.exs index f28925d72..40c3b7f88 100644 --- a/notifications/test/notifications/workers/coordinator/filter_test.exs +++ b/notifications/test/notifications/workers/coordinator/filter_test.exs @@ -51,12 +51,14 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r3, "pipeline", true, ".*") create_pattern(r3, "result", true, ".*") - assert names(Filter.find_rules(org1, "cli", "master", "", "prod.yml", "passed")) == [ + assert names(Filter.find_rules(org1, "cli", "master", "", "prod.yml", "passed", nil)) == [ "A", "B" ] - assert names(Filter.find_rules(org2, "cli", "master", "", "prod.yml", "failed")) == ["C"] + assert names(Filter.find_rules(org2, "cli", "master", "", "prod.yml", "failed", nil)) == [ + "C" + ] end end @@ -72,8 +74,11 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "pipeline", true, ".*") create_pattern(r, "result", true, ".*") - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == [] - assert names(Filter.find_rules(org, "cli", "master", "", "prod.yml", "passed")) == ["A"] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [] + + assert names(Filter.find_rules(org, "cli", "master", "", "prod.yml", "passed", nil)) == [ + "A" + ] end test "regex match" do @@ -87,8 +92,11 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "pipeline", true, ".*") create_pattern(r, "result", true, ".*") - assert names(Filter.find_rules(org, "s2-123", "master", "", "prod.yml", "passed")) == ["A"] - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == [] + assert names(Filter.find_rules(org, "s2-123", "master", "", "prod.yml", "passed", nil)) == [ + "A" + ] + + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [] end end @@ -104,11 +112,22 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "pipeline", true, ".*") create_pattern(r, "result", true, ".*") - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == ["A"] - assert names(Filter.find_rules(org, "api", "staging", "", "prod.yml", "passed")) == [] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [ + "A" + ] + + assert names(Filter.find_rules(org, "api", "staging", "", "prod.yml", "passed", nil)) == [] assert names( - Filter.find_rules(org, "api", "pull-request-54348", "master", "prod.yml", "passed") + Filter.find_rules( + org, + "api", + "pull-request-54348", + "master", + "prod.yml", + "passed", + nil + ) ) == ["A"] end @@ -123,11 +142,12 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "pipeline", true, ".*") create_pattern(r, "result", true, ".*") - assert names(Filter.find_rules(org, "api", "staging-123", "", "prod.yml", "passed")) == [ - "A" - ] + assert names(Filter.find_rules(org, "api", "staging-123", "", "prod.yml", "passed", nil)) == + [ + "A" + ] - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == [] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [] assert names( Filter.find_rules( @@ -154,11 +174,12 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "branch", true, ".*") create_pattern(r, "result", true, ".*") - assert names(Filter.find_rules(org, "api", "master", "", "semaphore.yml", "passed")) == [ - "A" - ] + assert names(Filter.find_rules(org, "api", "master", "", "semaphore.yml", "passed", nil)) == + [ + "A" + ] - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == [] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [] end test "regex match" do @@ -172,11 +193,12 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "branch", true, ".*") create_pattern(r, "result", true, ".*") - assert names(Filter.find_rules(org, "api", "master", "", "stg-alpha.yml", "passed")) == [ - "A" - ] + assert names(Filter.find_rules(org, "api", "master", "", "stg-alpha.yml", "passed", nil)) == + [ + "A" + ] - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == [] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [] end end @@ -192,11 +214,12 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "branch", true, ".*") create_pattern(r, "pipeline", true, ".*") - assert names(Filter.find_rules(org, "api", "master", "", "semaphore.yml", "failed")) == [ - "A" - ] + assert names(Filter.find_rules(org, "api", "master", "", "semaphore.yml", "failed", nil)) == + [ + "A" + ] - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed")) == [] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [] end test "regex match" do @@ -210,10 +233,133 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r, "branch", true, ".*") create_pattern(r, "pipeline", true, ".*") - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "failed")) == [] - assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "exited")) == [] - assert names(Filter.find_rules(org, "api", "master", "", "stg.yml", "passed")) == ["A"] - assert names(Filter.find_rules(org, "api", "master", "", "stg.yml", "stopped")) == ["A"] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "failed", nil)) == [] + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "exited", nil)) == [] + assert names(Filter.find_rules(org, "api", "master", "", "stg.yml", "passed", nil)) == ["A"] + + assert names(Filter.find_rules(org, "api", "master", "", "stg.yml", "stopped", nil)) == [ + "A" + ] + end + end + + describe "filter by tag" do + test "exact match" do + org = Ecto.UUID.generate() + r = create_rule("A", org) + + create_pattern(r, "tag", false, "v1.0.0") + + # match every project/branch/pipeline/result + create_pattern(r, "project", true, ".*") + create_pattern(r, "branch", true, ".*") + create_pattern(r, "pipeline", true, ".*") + create_pattern(r, "result", true, ".*") + + # Should match when tag is provided and matches pattern + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v1.0.0")) == + ["A"] + + # Should not match when tag doesn't match pattern + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v2.0.0")) == + [] + + # When tag patterns exist but nil is passed, it skips tag filtering + # So the rule WILL match (because all other patterns match) + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [ + "A" + ] + end + + test "regex match" do + org = Ecto.UUID.generate() + r = create_rule("A", org) + + create_pattern(r, "tag", true, "^v\\d+\\.\\d+\\.\\d+$") + + # match every project/branch/pipeline/result + create_pattern(r, "project", true, ".*") + create_pattern(r, "branch", true, ".*") + create_pattern(r, "pipeline", true, ".*") + create_pattern(r, "result", true, ".*") + + # Should match semantic version tags + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v1.0.0")) == + ["A"] + + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v2.1.3")) == + ["A"] + + # Should not match non-semantic version tags + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "release-1")) == + [] + + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v1.0")) == + [] + + # When tag patterns exist but nil is passed, it skips tag filtering + # So the rule WILL match (because all other patterns match) + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == [ + "A" + ] + end + + test "wildcard-style match with release prefix" do + org = Ecto.UUID.generate() + r = create_rule("A", org) + + create_pattern(r, "tag", true, "^release-.*") + + # match every project/branch/pipeline/result + create_pattern(r, "project", true, ".*") + create_pattern(r, "branch", true, ".*") + create_pattern(r, "pipeline", true, ".*") + create_pattern(r, "result", true, ".*") + + # Should match release tags + assert names( + Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "release-1.0") + ) == ["A"] + + assert names( + Filter.find_rules( + org, + "api", + "master", + "", + "prod.yml", + "passed", + "release-staging" + ) + ) == ["A"] + + # Should not match other tags + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v1.0.0")) == + [] + + assert names( + Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "hotfix-123") + ) == [] + end + + test "should match when no tag patterns exist (default behavior)" do + org = Ecto.UUID.generate() + r = create_rule("A", org) + + # Create patterns for all other types, including the default tag pattern + create_pattern(r, "project", true, ".*") + create_pattern(r, "branch", true, ".*") + create_pattern(r, "pipeline", true, ".*") + create_pattern(r, "result", true, ".*") + # This is the default pattern rule_factory would add + create_pattern(r, "tag", true, ".*") + + # When the default ".*" tag pattern exists, the rule should match ANY tag value (including nil) + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", "v1.0.0")) == + ["A"] + + assert names(Filter.find_rules(org, "api", "master", "", "prod.yml", "passed", nil)) == + ["A"] end end @@ -250,6 +396,6 @@ defmodule Notifications.Workers.Coordinator.FilterTest do create_pattern(r1, "block", true, ".*") create_pattern(r1, "result", true, ".*") - assert names(Filter.find_rules(org1, "a", "stg", "", "semaphore.yml", "passed")) == ["A"] + assert names(Filter.find_rules(org1, "a", "stg", "", "semaphore.yml", "passed", nil)) == ["A"] end end diff --git a/notifications/test/notifications/workers/coordinator_test.exs b/notifications/test/notifications/workers/coordinator_test.exs index 18db4a45d..f4e897f85 100644 --- a/notifications/test/notifications/workers/coordinator_test.exs +++ b/notifications/test/notifications/workers/coordinator_test.exs @@ -54,6 +54,63 @@ defmodule Notifications.Workers.CoordinatorTest do assert_called(Slack.publish(:_, :_, :_, :_)) end end + + test "when hook is a tag event with matching tag pattern" do + add_notification_with_tag_patterns() + authorize_everything() + mock_tag_hook("v1.0.0") + + with_mock Slack, publish: fn _, _, _, _ -> :ok end do + pipeline_event = InternalApi.Plumber.PipelineEvent.new(pipeline_id: @pipeline_id) + message = InternalApi.Plumber.PipelineEvent.encode(pipeline_event) + + assert PipelineFinished.handle_message(message) + assert_called(Slack.publish(:_, :_, :_, :_)) + end + end + + test "when hook is a tag event with non-matching tag pattern" do + add_notification_with_tag_patterns() + authorize_everything() + mock_tag_hook("hotfix-123") + + with_mock Slack, publish: fn _, _, _, _ -> :ok end do + pipeline_event = InternalApi.Plumber.PipelineEvent.new(pipeline_id: @pipeline_id) + message = InternalApi.Plumber.PipelineEvent.encode(pipeline_event) + + assert PipelineFinished.handle_message(message) + assert_not_called(Slack.publish(:_, :_, :_, :_)) + end + end + + test "when hook is a tag event with branch patterns - should ignore branch filtering" do + add_notification_with_branch_and_tag_patterns() + authorize_everything() + mock_tag_hook("v1.0.0") + + with_mock Slack, publish: fn _, _, _, _ -> :ok end do + pipeline_event = InternalApi.Plumber.PipelineEvent.new(pipeline_id: @pipeline_id) + message = InternalApi.Plumber.PipelineEvent.encode(pipeline_event) + + assert PipelineFinished.handle_message(message) + # Should trigger despite branch_name being "refs/tags/v1.0.0" which doesn't match "master" + assert_called(Slack.publish(:_, :_, :_, :_)) + end + end + + test "when hook is a regular branch event - should work normally" do + add_notification_with_branch_and_tag_patterns() + authorize_everything() + mock_branch_hook("master") + + with_mock Slack, publish: fn _, _, _, _ -> :ok end do + pipeline_event = InternalApi.Plumber.PipelineEvent.new(pipeline_id: @pipeline_id) + message = InternalApi.Plumber.PipelineEvent.encode(pipeline_event) + + assert PipelineFinished.handle_message(message) + assert_called(Slack.publish(:_, :_, :_, :_)) + end + end end ### @@ -81,7 +138,13 @@ defmodule Notifications.Workers.CoordinatorTest do fn _, _ -> Plumber.DescribeResponse.new( response_status: Plumber.ResponseStatus.new(code: :OK), - pipeline: Plumber.Pipeline.new(project_id: @project_id) + pipeline: + Plumber.Pipeline.new( + project_id: @project_id, + branch_name: "master", + yaml_file_name: "semaphore.yml", + result: :PASSED + ) ) end ) @@ -92,7 +155,12 @@ defmodule Notifications.Workers.CoordinatorTest do fn _, _ -> project = Projecthub.Project.new( - metadata: Projecthub.Project.Metadata.new(id: @project_id, org_id: @org_id) + metadata: + Projecthub.Project.Metadata.new( + id: @project_id, + org_id: @org_id, + name: "test-project" + ) ) Projecthub.DescribeResponse.new( @@ -221,4 +289,183 @@ defmodule Notifications.Workers.CoordinatorTest do rule end + + defp add_notification_with_tag_patterns do + notification = + Repo.insert!(%Notification{ + org_id: @org_id, + creator_id: @creator_id, + name: "Test Tag Notification", + spec: %{"rules" => []} + }) + + create_rule_with_tag_patterns(notification) + end + + defp add_notification_with_branch_and_tag_patterns do + notification = + Repo.insert!(%Notification{ + org_id: @org_id, + creator_id: @creator_id, + name: "Test Branch and Tag Notification", + spec: %{"rules" => []} + }) + + create_rule_with_branch_and_tag_patterns(notification) + end + + defp create_rule_with_tag_patterns(notification) do + rule = + Repo.insert!(%Rule{ + org_id: @org_id, + notification_id: notification.id, + name: "Test Tag Rule", + slack: %{ + "endpoint" => "https://hooks.slack.com/services/TEST", + "channels" => ["#test-channel"] + }, + email: %{}, + webhook: %{} + }) + + # Add patterns that will match tags starting with "v" + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "project", + regex: true, + term: ".*" + }) + + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "pipeline", + regex: true, + term: ".*" + }) + + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "result", + regex: true, + term: ".*" + }) + + # Tag pattern that matches "v*" + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "tag", + regex: true, + term: "^v.*" + }) + + rule + end + + defp create_rule_with_branch_and_tag_patterns(notification) do + rule = + Repo.insert!(%Rule{ + org_id: @org_id, + notification_id: notification.id, + name: "Test Branch and Tag Rule", + slack: %{ + "endpoint" => "https://hooks.slack.com/services/TEST", + "channels" => ["#test-channel"] + }, + email: %{}, + webhook: %{} + }) + + # Add patterns for all types + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "project", + regex: true, + term: ".*" + }) + + # Branch pattern that only matches "master" + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "branch", + regex: false, + term: "master" + }) + + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "pipeline", + regex: true, + term: ".*" + }) + + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "result", + regex: true, + term: ".*" + }) + + # Tag pattern that matches all tags (works for both branch and tag events) + Repo.insert!(%Pattern{ + org_id: @org_id, + rule_id: rule.id, + type: "tag", + regex: true, + term: ".*" + }) + + rule + end + + defp mock_tag_hook(tag_name) do + GrpcMock.stub( + RepoProxyMock, + :describe, + fn _, _ -> + alias InternalApi.{RepoProxy, ResponseStatus} + + RepoProxy.DescribeResponse.new( + status: ResponseStatus.new(code: ResponseStatus.Code.value(:OK)), + hook: + RepoProxy.Hook.new( + git_ref_type: :TAG, + git_ref: tag_name, + branch_name: "refs/tags/#{tag_name}", + pr_branch_name: "", + tag_name: tag_name + ) + ) + end + ) + end + + defp mock_branch_hook(branch_name) do + GrpcMock.stub( + RepoProxyMock, + :describe, + fn _, _ -> + alias InternalApi.{RepoProxy, ResponseStatus} + + RepoProxy.DescribeResponse.new( + status: ResponseStatus.new(code: ResponseStatus.Code.value(:OK)), + hook: + RepoProxy.Hook.new( + git_ref_type: :BRANCH, + git_ref: branch_name, + branch_name: branch_name, + pr_branch_name: "", + tag_name: "" + ) + ) + end + ) + end end