Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e996e53
chore: types and mutations
nimish-ks Jan 3, 2026
b1e7ef2
feat: request org scope when setting up auth
nimish-ks Jan 3, 2026
99a6626
feat: add GraphQL query to fetch GitHub organizations
nimish-ks Jan 3, 2026
28b4e85
feat: update CreateGhActionsSync mutation to include orgSync and repo…
nimish-ks Jan 3, 2026
147fc90
feat: enhance GitHub actions sync to support organization-level secre…
nimish-ks Jan 3, 2026
1ab0c60
feat: implement organization management features for GitHub actions, …
nimish-ks Jan 3, 2026
e578944
feat: add GraphQL query and resolver for GitHub organizations in schema
nimish-ks Jan 3, 2026
3e3aabe
feat: add resolver for fetching GitHub organizations in GraphQL
nimish-ks Jan 3, 2026
09ec80b
feat: update CreateGitHubActionsSync mutation to require repo_name fo…
nimish-ks Jan 3, 2026
a983068
feat: enhance ServiceInfo component to display organization sync deta…
nimish-ks Jan 3, 2026
d885021
feat: enhance CreateGhActionsSync component to support organization s…
nimish-ks Jan 3, 2026
90d07c7
Update backend/api/utils/syncing/github/actions.py
nimish-ks Jan 5, 2026
ecc0852
feat: update CreateGitHubActionsSync mutation to require owner for Gi…
nimish-ks Jan 5, 2026
c2476fc
fix: handle oversized GitHub secrets by returning a descriptive error…
nimish-ks Jan 5, 2026
965cff5
fix: update test for GitHub secrets syncing to assert handling of ove…
nimish-ks Jan 5, 2026
ce18083
Update frontend/components/syncing/GitHub/CreateGhActionsSync.tsx
nimish-ks Jan 5, 2026
9078eb9
fix: update default message in FormattedJSON component from 'No detai…
nimish-ks Jan 5, 2026
338c0ca
fix: prevent duplicate GitHub organization syncs and refine repo sync…
nimish-ks Jan 5, 2026
62391d1
fix: not fetch member role
nimish-ks Jan 5, 2026
2383ef8
fix: replace null with undefined for selectedRepo and selectedOrg in …
nimish-ks Jan 5, 2026
280d8d7
feat: add CreateGitHubDependabotSync mutation to support GitHub Depen…
nimish-ks Jan 5, 2026
df156be
feat: implement GitHub Dependabot secrets synchronization functions
nimish-ks Jan 5, 2026
f1bc5be
feat: add GitHub Dependabot configuration to ServiceConfig
nimish-ks Jan 5, 2026
3a12700
feat: implement GitHub Dependabot sync task and update environment sy…
nimish-ks Jan 5, 2026
d78a7e1
feat: add create_gh_dependabot_sync field to Mutation for GitHub Depe…
nimish-ks Jan 5, 2026
220eacd
feat: implement CreateGitHubDependabotSync mutation for enhanced GitH…
nimish-ks Jan 5, 2026
91172bd
feat: add CreateNewGhDependabotSync mutation to support GitHub Depend…
nimish-ks Jan 5, 2026
180dc9d
feat: add CreateNewGhDependabotSync mutation and related types for Gi…
nimish-ks Jan 5, 2026
4c9ee56
feat: add CreateGhDependabotSync mutation for GitHub Dependabot synch…
nimish-ks Jan 5, 2026
05ff6fe
feat: implement CreateGhDependabotSync component for GitHub Dependabo…
nimish-ks Jan 5, 2026
1e14c63
feat: integrate CreateGhDependabotSync into CreateSyncDialog for GitH…
nimish-ks Jan 5, 2026
7f3691f
feat: enhance ServiceInfo component to display organization and repos…
nimish-ks Jan 5, 2026
e4f440c
test: add unit tests for GitHub Dependabot secrets synchronization an…
nimish-ks Jan 5, 2026
5900c6f
refactor: remove unused service_config variable from CreateGitHubDepe…
nimish-ks Jan 5, 2026
62e04b6
refactor: remove unused data variable from CreateGhDependabotSync mut…
nimish-ks Jan 5, 2026
bda63e0
Update frontend/components/syncing/GitHub/CreateGhDependabotSync.tsx
nimish-ks Jan 5, 2026
c364131
Update backend/backend/graphene/mutations/syncing.py
nimish-ks Jan 5, 2026
cb3aed2
Merge branch 'main' into feat--sync-secrets-github-organization
nimish-ks Jan 6, 2026
0d0e5e1
Merge branch 'main' into feat--sync-secrets-github-organization
nimish-ks Jan 11, 2026
be60fe4
fix: update app host retrieval in GitHub actions normalization
nimish-ks Jan 11, 2026
033bf69
Merge branch 'main' into feat--sync-secrets-github-organization
rohan-chaturvedi Jan 14, 2026
2762078
fix: ensure sync jobs gracefully handle cases where credentials are r…
rohan-chaturvedi Jan 16, 2026
c9414c9
feat: add permission checks for accessing GitHub environments and org…
rohan-chaturvedi Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions backend/api/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ class ServiceConfig:
"provider": Providers.GITHUB,
"resource_type": "repo",
}

GITHUB_DEPENDABOT = {
"id": "github_dependabot",
"name": "GitHub Dependabot",
"provider": Providers.GITHUB,
"resource_type": "repo",
}

GITLAB_CI = {
"id": "gitlab_ci",
Expand Down
160 changes: 133 additions & 27 deletions backend/api/tasks/syncing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
from api.utils.syncing.github.actions import (
get_gh_actions_credentials,
sync_github_secrets,
sync_github_org_secrets,
)
from api.utils.syncing.github.dependabot import (
sync_github_dependabot_secrets,
sync_github_dependabot_org_secrets,
)
from api.utils.syncing.vault.main import sync_vault_secrets
from api.utils.syncing.nomad.main import sync_nomad_secrets
Expand Down Expand Up @@ -84,6 +89,15 @@ def trigger_sync_tasks(env_sync):

EnvironmentSyncEvent.objects.create(id=job_id, env_sync=env_sync)

elif env_sync.service == ServiceConfig.GITHUB_DEPENDABOT["id"]:
env_sync.status = EnvironmentSync.IN_PROGRESS
env_sync.save()

job = perform_github_dependabot_sync.delay(env_sync)
job_id = job.get_id()

EnvironmentSyncEvent.objects.create(id=job_id, env_sync=env_sync)

elif env_sync.service == ServiceConfig.HASHICORP_VAULT["id"]:
env_sync.status = EnvironmentSync.IN_PROGRESS
env_sync.save()
Expand Down Expand Up @@ -238,7 +252,12 @@ def handle_sync_event(environment_sync, sync_function, *args, **kwargs):
@job("default", timeout=DEFAULT_TIMEOUT)
def perform_cloudflare_pages_sync(environment_sync):

account_id, access_token = get_cf_pages_credentials(environment_sync)
account_id = None
access_token = None

if environment_sync.authentication:
account_id, access_token = get_cf_pages_credentials(environment_sync)

project_info = environment_sync.options

handle_sync_event(
Expand All @@ -254,33 +273,92 @@ def perform_cloudflare_pages_sync(environment_sync):
@job("default", timeout=DEFAULT_TIMEOUT)
def perform_github_actions_sync(environment_sync):

access_token, api_host = get_gh_actions_credentials(environment_sync)
repo_name = environment_sync.options.get("repo_name")
repo_owner = environment_sync.options.get("owner")
environment_name = environment_sync.options.get("environment_name")
access_token = None
api_host = None

if environment_sync.authentication:
access_token, api_host = get_gh_actions_credentials(environment_sync)

is_org_sync = environment_sync.options.get("org_sync", False)

if is_org_sync:
org = environment_sync.options.get("org")
visibility = environment_sync.options.get("visibility", "all")
handle_sync_event(
environment_sync,
sync_github_org_secrets,
access_token,
org,
api_host,
visibility,
)
else:
repo_name = environment_sync.options.get("repo_name")
repo_owner = environment_sync.options.get("owner")
environment_name = environment_sync.options.get("environment_name")

handle_sync_event(
environment_sync,
sync_github_secrets,
access_token,
repo_name,
repo_owner,
api_host,
environment_name,
)

handle_sync_event(
environment_sync,
sync_github_secrets,
access_token,
repo_name,
repo_owner,
api_host,
environment_name,
)

@job("default", timeout=DEFAULT_TIMEOUT)
def perform_github_dependabot_sync(environment_sync):

access_token = None
api_host = None

if environment_sync.authentication:
access_token, api_host = get_gh_actions_credentials(environment_sync)

is_org_sync = environment_sync.options.get("org_sync", False)

if is_org_sync:
org = environment_sync.options.get("org")
visibility = environment_sync.options.get("visibility", "all")
handle_sync_event(
environment_sync,
sync_github_dependabot_org_secrets,
access_token,
org,
api_host,
visibility,
)
else:
repo_name = environment_sync.options.get("repo_name")
repo_owner = environment_sync.options.get("owner")

handle_sync_event(
environment_sync,
sync_github_dependabot_secrets,
access_token,
repo_name,
repo_owner,
api_host,
)


@job("default", timeout=DEFAULT_TIMEOUT)
def perform_aws_sm_sync(environment_sync):
project_info = environment_sync.options

# Determine authentication method and get appropriate credentials
has_role_arn = "role_arn" in environment_sync.authentication.credentials
credentials = {}

if environment_sync.authentication:
has_role_arn = "role_arn" in environment_sync.authentication.credentials

if has_role_arn:
credentials = get_aws_assume_role_credentials(environment_sync)
else:
credentials = get_aws_secrets_manager_credentials(environment_sync)

if has_role_arn:
credentials = get_aws_assume_role_credentials(environment_sync)
else:
credentials = get_aws_secrets_manager_credentials(environment_sync)
handle_sync_event(
environment_sync,
sync_aws_secrets,
Expand All @@ -300,10 +378,14 @@ def perform_vault_sync(environment_sync):

project_info = environment_sync.options

auth_id = None
if environment_sync.authentication:
auth_id = environment_sync.authentication.id

handle_sync_event(
environment_sync,
sync_vault_secrets,
environment_sync.authentication.id,
auth_id,
project_info.get("engine"),
project_info.get("path"),
)
Expand All @@ -314,10 +396,14 @@ def perform_nomad_sync(environment_sync):

project_info = environment_sync.options

auth_id = None
if environment_sync.authentication:
auth_id = environment_sync.authentication.id

handle_sync_event(
environment_sync,
sync_nomad_secrets,
environment_sync.authentication.id,
auth_id,
project_info.get("path"),
project_info.get("namespace"),
)
Expand All @@ -330,10 +416,14 @@ def perform_gitlab_sync(environment_sync):
resource_id = project_info.get("resource_id")
resource_path = project_info.get("resource_path")

auth_id = None
if environment_sync.authentication:
auth_id = environment_sync.authentication.id

handle_sync_event(
environment_sync,
sync_gitlab_secrets,
environment_sync.authentication.id,
auth_id,
resource_id if resource_id is not None else resource_path,
project_info.get("is_group"),
project_info.get("masked"),
Expand All @@ -350,10 +440,14 @@ def perform_railway_sync(environment_sync):
railway_environment = railway_sync_options.get("environment")
railway_service = railway_sync_options.get("service")

auth_id = None
if environment_sync.authentication:
auth_id = environment_sync.authentication.id

handle_sync_event(
environment_sync,
sync_railway_secrets,
environment_sync.authentication.id,
auth_id,
railway_project["id"],
railway_environment["id"],
railway_service["id"] if railway_service is not None else None,
Expand All @@ -370,10 +464,14 @@ def perform_vercel_sync(environment_sync):
vercel_environment = vercel_sync_options.get("environment", "production")
vercel_secret_type = vercel_sync_options.get("secret_type", "encrypted")

auth_id = None
if environment_sync.authentication:
auth_id = environment_sync.authentication.id

handle_sync_event(
environment_sync,
sync_vercel_secrets,
environment_sync.authentication.id,
auth_id,
vercel_project["id"],
vercel_team["id"] if vercel_team is not None else None,
vercel_environment,
Expand All @@ -383,7 +481,11 @@ def perform_vercel_sync(environment_sync):

@job("default", timeout=DEFAULT_TIMEOUT)
def perform_cloudflare_workers_sync(environment_sync):
account_id, access_token = get_cf_workers_credentials(environment_sync)
account_id = None
access_token = None

if environment_sync.authentication:
account_id, access_token = get_cf_workers_credentials(environment_sync)

worker_info = environment_sync.options

Expand All @@ -402,13 +504,17 @@ def perform_render_service_sync(environment_sync):
render_resource_id = render_service_options.get("resource_id")
render_resource_type = render_service_options.get("resource_type")

auth_id = None
if environment_sync.authentication:
auth_id = environment_sync.authentication.id

if render_resource_type == RenderResourceType.ENVIRONMENT_GROUP.value:
secret_file_name = render_service_options.get("secret_file_name")

handle_sync_event(
environment_sync,
sync_render_env_group_secret_file,
environment_sync.authentication.id,
auth_id,
render_resource_id,
secret_file_name,
)
Expand All @@ -417,6 +523,6 @@ def perform_render_service_sync(environment_sync):
handle_sync_event(
environment_sync,
sync_render_service_env_vars,
environment_sync.authentication.id,
auth_id,
render_resource_id,
)
Loading