From 8f88a3f03f50f1339055387b50748030442a9df7 Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:20:27 +0530 Subject: [PATCH 01/12] feat: add environment support to github actions sync --- backend/api/utils/syncing/github/actions.py | 104 ++++++++++++++++++-- 1 file changed, 94 insertions(+), 10 deletions(-) diff --git a/backend/api/utils/syncing/github/actions.py b/backend/api/utils/syncing/github/actions.py index a35ea4f80..fafc33659 100644 --- a/backend/api/utils/syncing/github/actions.py +++ b/backend/api/utils/syncing/github/actions.py @@ -100,6 +100,50 @@ def get_gh_actions_credentials(environment_sync): return access_token, api_host +def list_environments(credential_id, owner, repo_name): + """Return a list of GitHub Actions environment names for a repo. + + This requires at least the `repo` scope on the OAuth token. + """ + ProviderCredentials = apps.get_model("api", "ProviderCredentials") + + pk, sk = get_server_keypair() + credential = ProviderCredentials.objects.get(id=credential_id) + + access_token = decrypt_asymmetric( + credential.credentials["access_token"], sk.hex(), pk.hex() + ) + + api_host = GITHUB_CLOUD_API_URL + if "host" in credential.credentials: + api_host = decrypt_asymmetric( + credential.credentials["api_url"], sk.hex(), pk.hex() + ) + + api_host = normalize_api_host(api_host) + + headers = {"Authorization": f"Bearer {access_token}", "Accept": "application/vnd.github+json"} + + environments = [] + page = 1 + while True: + url = f"{api_host}/repos/{owner}/{repo_name}/environments?per_page=100&page={page}" + response = requests.get(url, headers=headers) + if response.status_code != 200: + raise Exception( + f"Error fetching environments: {response.status_code} {response.text}" + ) + + payload = response.json() + items = payload.get("environments", []) + if not items: + break + environments.extend([env.get("name") for env in items if env.get("name")]) + page += 1 + + return environments + + def encrypt_secret(public_key: str, secret_value: str) -> str: pk = nacl.public.PublicKey(public_key, nacl.encoding.Base64Encoder()) box = nacl.public.SealedBox(pk) @@ -136,8 +180,29 @@ def get_all_secrets(repo, owner, headers, api_host=GITHUB_CLOUD_API_URL): return all_secrets +def get_all_env_secrets(repo, owner, environment_name, headers, api_host=GITHUB_CLOUD_API_URL): + api_host = normalize_api_host(api_host) + all_secrets = [] + page = 1 + while True: + response = requests.get( + f"{api_host}/repos/{owner}/{repo}/environments/{environment_name}/secrets?page={page}", + headers=headers, + ) + if response.status_code != 200 or not response.json().get("secrets"): + break + all_secrets.extend(response.json()["secrets"]) + page += 1 + return all_secrets + + def sync_github_secrets( - secrets, access_token, repo, owner, api_host=GITHUB_CLOUD_API_URL + secrets, + access_token, + repo, + owner, + api_host=GITHUB_CLOUD_API_URL, + environment_name=None, ): api_host = normalize_api_host(api_host) @@ -150,10 +215,14 @@ def sync_github_secrets( "Accept": "application/vnd.github+json", } - public_key_response = requests.get( - f"{api_host}/repos/{owner}/{repo}/actions/secrets/public-key", - headers=headers, - ) + if environment_name: + public_key_url = ( + f"{api_host}/repos/{owner}/{repo}/environments/{environment_name}/secrets/public-key" + ) + else: + public_key_url = f"{api_host}/repos/{owner}/{repo}/actions/secrets/public-key" + + public_key_response = requests.get(public_key_url, headers=headers) if public_key_response.status_code != 200: return False, { "response_code": public_key_response.status_code, @@ -165,7 +234,12 @@ def sync_github_secrets( public_key_value = public_key["key"] local_secrets = {k: v for k, v, _ in secrets} - existing_secrets = get_all_secrets(repo, owner, headers, api_host) + if environment_name: + existing_secrets = get_all_env_secrets( + repo, owner, environment_name, headers, api_host + ) + else: + existing_secrets = get_all_secrets(repo, owner, headers, api_host) existing_secret_names = {secret["name"] for secret in existing_secrets} for key, value in local_secrets.items(): @@ -174,7 +248,12 @@ def sync_github_secrets( continue # Skip oversized secret secret_data = {"encrypted_value": encrypted_value, "key_id": key_id} - secret_url = f"{api_host}/repos/{owner}/{repo}/actions/secrets/{key}" + if environment_name: + secret_url = ( + f"{api_host}/repos/{owner}/{repo}/environments/{environment_name}/secrets/{key}" + ) + else: + secret_url = f"{api_host}/repos/{owner}/{repo}/actions/secrets/{key}" response = requests.put(secret_url, headers=headers, json=secret_data) if response.status_code not in [201, 204]: @@ -185,9 +264,14 @@ def sync_github_secrets( for secret_name in existing_secret_names: if secret_name not in local_secrets: - delete_url = ( - f"{api_host}/repos/{owner}/{repo}/actions/secrets/{secret_name}" - ) + if environment_name: + delete_url = ( + f"{api_host}/repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}" + ) + else: + delete_url = ( + f"{api_host}/repos/{owner}/{repo}/actions/secrets/{secret_name}" + ) delete_response = requests.delete(delete_url, headers=headers) if delete_response.status_code != 204: return False, { From 5bb76527c555afbd77caec3e3da56fccc268d3fe Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:20:39 +0530 Subject: [PATCH 02/12] feat: include environment name in GitHub actions sync function --- backend/api/tasks/syncing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/api/tasks/syncing.py b/backend/api/tasks/syncing.py index f23addd22..3b42bbb00 100644 --- a/backend/api/tasks/syncing.py +++ b/backend/api/tasks/syncing.py @@ -257,6 +257,7 @@ 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") handle_sync_event( environment_sync, @@ -265,6 +266,7 @@ def perform_github_actions_sync(environment_sync): repo_name, repo_owner, api_host, + environment_name, ) From 5717186fe72a5b9e518d8bfd6e0f70726186f835 Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:38:29 +0530 Subject: [PATCH 03/12] feat: add GitHub environments resolver and query to schema --- backend/backend/schema.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/backend/schema.py b/backend/backend/schema.py index 1496c7eef..def88f21a 100644 --- a/backend/backend/schema.py +++ b/backend/backend/schema.py @@ -66,6 +66,7 @@ from .graphene.queries.syncing import ( resolve_aws_secret_manager_secrets, resolve_gh_repos, + resolve_github_environments, resolve_gitlab_projects, resolve_gitlab_groups, resolve_server_public_key, @@ -373,6 +374,9 @@ class Query(graphene.ObjectType): GitHubRepoType, credential_id=graphene.ID(), ) + github_environments = graphene.List( + graphene.String, credential_id=graphene.ID(), owner=graphene.String(), repo_name=graphene.String() + ) gitlab_projects = graphene.List(GitLabProjectType, credential_id=graphene.ID()) gitlab_groups = graphene.List(GitLabGroupType, credential_id=graphene.ID()) @@ -447,6 +451,7 @@ class Query(graphene.ObjectType): resolve_aws_secrets = resolve_aws_secret_manager_secrets resolve_github_repos = resolve_gh_repos + resolve_github_environments = resolve_github_environments resolve_gitlab_projects = resolve_gitlab_projects resolve_gitlab_groups = resolve_gitlab_groups From 45e4db0e2adae1d873015193bdc6b290dab50ea2 Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:38:42 +0530 Subject: [PATCH 04/12] feat: add optional environment name parameter to GitHub actions sync mutation --- backend/backend/graphene/mutations/syncing.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/backend/graphene/mutations/syncing.py b/backend/backend/graphene/mutations/syncing.py index f032cde79..b1970b06a 100644 --- a/backend/backend/graphene/mutations/syncing.py +++ b/backend/backend/graphene/mutations/syncing.py @@ -266,11 +266,14 @@ class Arguments: credential_id = graphene.ID() repo_name = graphene.String() owner = graphene.String() + environment_name = graphene.String(required=False) sync = graphene.Field(EnvironmentSyncType) @classmethod - def mutate(cls, root, info, env_id, path, credential_id, repo_name, owner): + def mutate( + cls, root, info, env_id, path, credential_id, repo_name, owner, environment_name=None + ): service_id = "github_actions" service_config = ServiceConfig.get_service_config(service_id) @@ -283,6 +286,8 @@ def mutate(cls, root, info, env_id, path, credential_id, repo_name, owner): raise GraphQLError("You don't have access to this app") sync_options = {"repo_name": repo_name, "owner": owner} + if environment_name: + sync_options["environment_name"] = environment_name existing_syncs = EnvironmentSync.objects.filter( environment__app_id=env.app.id, service=service_id, deleted_at=None From 292c2fca92bb1b0f4f5441e4e2cd44f7b968bc3d Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:39:17 +0530 Subject: [PATCH 05/12] feat: add resolver for GitHub environments to fetch environment details --- backend/backend/graphene/queries/syncing.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/backend/graphene/queries/syncing.py b/backend/backend/graphene/queries/syncing.py index 164228872..ba427a5e0 100644 --- a/backend/backend/graphene/queries/syncing.py +++ b/backend/backend/graphene/queries/syncing.py @@ -20,7 +20,7 @@ ) from api.services import Providers, ServiceConfig from api.utils.syncing.aws.secrets_manager import list_aws_secrets -from api.utils.syncing.github.actions import list_repos +from api.utils.syncing.github.actions import list_repos, list_environments from api.utils.syncing.vault.main import test_vault_creds from api.utils.syncing.nomad.main import test_nomad_creds from api.utils.syncing.gitlab.main import list_gitlab_groups, list_gitlab_projects @@ -191,6 +191,14 @@ def resolve_gh_repos(root, info, credential_id): raise GraphQLError(ex) +def resolve_github_environments(root, info, credential_id, owner, repo_name): + try: + envs = list_environments(credential_id, owner, repo_name) + return envs + except Exception as ex: + raise GraphQLError(ex) + + def resolve_test_vault_creds(root, info, credential_id): try: valid = test_vault_creds(credential_id) From 9b65be9a8b2d879e80c022fafaf5be4c237965f0 Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:39:59 +0530 Subject: [PATCH 06/12] refactor: streamline GraphQL schema by consolidating query and mutation parameters for improved readability --- frontend/apollo/schema.graphql | 478 ++++++--------------------------- 1 file changed, 80 insertions(+), 398 deletions(-) diff --git a/frontend/apollo/schema.graphql b/frontend/apollo/schema.graphql index ce0f2e1b8..b3412f19e 100644 --- a/frontend/apollo/schema.graphql +++ b/frontend/apollo/schema.graphql @@ -13,22 +13,9 @@ type Query { validateInvite(inviteId: ID): OrganisationMemberInviteType apps(organisationId: ID, appId: ID): [AppType] kmsLogs(appId: ID, start: BigInt, end: BigInt): KMSLogsResponseType - secretLogs( - appId: ID - start: BigInt - end: BigInt - eventTypes: [String] - memberId: ID - memberType: MemberType - environmentId: ID - ): SecretLogsResponseType + secretLogs(appId: ID, start: BigInt, end: BigInt, eventTypes: [String], memberId: ID, memberType: MemberType, environmentId: ID): SecretLogsResponseType appActivityChart(appId: ID, period: TimeRange): [ChartDataPointType] - appEnvironments( - appId: ID - environmentId: ID - memberId: ID - memberType: MemberType - ): [EnvironmentType] + appEnvironments(appId: ID, environmentId: ID, memberId: ID, memberType: MemberType): [EnvironmentType] appUsers(appId: ID): [OrganisationMemberType] appServiceAccounts(appId: ID): [ServiceAccountType] secrets(envId: ID, path: String, id: ID): [SecretType] @@ -52,6 +39,7 @@ type Query { cloudflareWorkers(credentialId: ID): [CloudflareWorkerType] awsSecrets(credentialId: ID): [AWSSecretType] githubRepos(credentialId: ID): [GitHubRepoType] + githubEnvironments(credentialId: ID, owner: String, repoName: String): [String] gitlabProjects(credentialId: ID): [GitLabProjectType] gitlabGroups(credentialId: ID): [GitLabGroupType] railwayProjects(credentialId: ID): [RailwayProjectType] @@ -62,11 +50,7 @@ type Query { testVaultCreds(credentialId: ID): Boolean testNomadCreds(credentialId: ID): Boolean validateAwsAssumeRoleAuth: AWSValidationResultType - validateAwsAssumeRoleCredentials( - roleArn: String! - region: String - externalId: String - ): AWSValidationResultType + validateAwsAssumeRoleCredentials(roleArn: String!, region: String, externalId: String): AWSValidationResultType stripeCheckoutDetails(stripeSessionId: String!): StripeCheckoutDetails stripeSubscriptionDetails(organisationId: ID): StripeSubscriptionDetails stripeCustomerPortalUrl(organisationId: ID!): String @@ -95,19 +79,13 @@ value as specified by scalar DateTime enum ApiOrganisationPlanChoices { - """ - Free - """ + """Free""" FR - """ - Pro - """ + """Pro""" PR - """ - Enterprise - """ + """Enterprise""" EN } @@ -209,24 +187,16 @@ type EnvironmentType { } enum ApiEnvironmentEnvTypeChoices { - """ - Development - """ + """Development""" DEV - """ - Staging - """ + """Staging""" STAGING - """ - Production - """ + """Production""" PROD - """ - Custom - """ + """Custom""" CUSTOM } @@ -348,24 +318,16 @@ type ServiceAccountTokenType { } enum ApiSecretEventEventTypeChoices { - """ - Create - """ + """Create""" C - """ - Read - """ + """Read""" R - """ - Update - """ + """Update""" U - """ - Delete - """ + """Delete""" D } @@ -388,9 +350,7 @@ type DynamicSecretType { path: String! authentication: ProviderCredentialsType - """ - Which provider this secret is associated with. - """ + """Which provider this secret is associated with.""" provider: ApiDynamicSecretProviderChoices! config: DynamicSecretConfigUnion keyMap: [KeyMap] @@ -421,9 +381,7 @@ type ProviderType { } enum ApiDynamicSecretProviderChoices { - """ - AWS - """ + """AWS""" AWS } @@ -459,9 +417,7 @@ type DynamicSecretLeaseType { serviceAccount: ServiceAccountType ttl: Int - """ - Current status of the lease - """ + """Current status of the lease""" status: ApiDynamicSecretLeaseStatusChoices! credentials: LeaseCredentialsUnion createdAt: DateTime @@ -472,29 +428,19 @@ type DynamicSecretLeaseType { } enum ApiDynamicSecretLeaseStatusChoices { - """ - Created - """ + """Created""" CREATED - """ - Active - """ + """Active""" ACTIVE - """ - Renewed - """ + """Renewed""" RENEWED - """ - Revoked - """ + """Revoked""" REVOKED - """ - Expired - """ + """Expired""" EXPIRED } @@ -519,29 +465,19 @@ type DynamicSecretLeaseEventType { } enum ApiDynamicSecretLeaseEventEventTypeChoices { - """ - Created - """ + """Created""" CREATED - """ - Active - """ + """Active""" ACTIVE - """ - Renewed - """ + """Renewed""" RENEWED - """ - Revoked - """ + """Revoked""" REVOKED - """ - Expired - """ + """Expired""" EXPIRED } @@ -560,29 +496,19 @@ type EnvironmentSyncType { } enum ApiEnvironmentSyncStatusChoices { - """ - In progress - """ + """In progress""" IN_PROGRESS - """ - Completed - """ + """Completed""" COMPLETED - """ - cancelled - """ + """cancelled""" CANCELLED - """ - Timed out - """ + """Timed out""" TIMED_OUT - """ - Failed - """ + """Failed""" FAILED } @@ -603,29 +529,19 @@ type EnvironmentSyncEventType { } enum ApiEnvironmentSyncEventStatusChoices { - """ - In progress - """ + """In progress""" IN_PROGRESS - """ - Completed - """ + """Completed""" COMPLETED - """ - cancelled - """ + """cancelled""" CANCELLED - """ - Timed out - """ + """Timed out""" TIMED_OUT - """ - Failed - """ + """Failed""" FAILED } @@ -688,19 +604,13 @@ type ActivatedPhaseLicenseType { } enum ApiActivatedPhaseLicensePlanChoices { - """ - Free - """ + """Free""" FR - """ - Pro - """ + """Pro""" PR - """ - Enterprise - """ + """Enterprise""" EN } @@ -755,13 +665,9 @@ type KMSLogType implements Node { longitude: Float } -""" -An object with an ID -""" +"""An object with an ID""" interface Node { - """ - The ID of the object - """ + """The ID of the object""" id: ID! } @@ -999,253 +905,62 @@ type DynamicSecretProviderType { } type Mutation { - createOrganisation( - id: ID! - identityKey: String! - name: String! - wrappedKeyring: String! - wrappedRecovery: String! - ): CreateOrganisationMutation - bulkInviteOrganisationMembers( - invites: [InviteInput]! - orgId: ID! - ): BulkInviteOrganisationMembersMutation - createOrganisationMember( - identityKey: String! - inviteId: ID! - orgId: ID! - wrappedKeyring: String - wrappedRecovery: String - ): CreateOrganisationMemberMutation + createOrganisation(id: ID!, identityKey: String!, name: String!, wrappedKeyring: String!, wrappedRecovery: String!): CreateOrganisationMutation + bulkInviteOrganisationMembers(invites: [InviteInput]!, orgId: ID!): BulkInviteOrganisationMembersMutation + createOrganisationMember(identityKey: String!, inviteId: ID!, orgId: ID!, wrappedKeyring: String, wrappedRecovery: String): CreateOrganisationMemberMutation deleteOrganisationMember(memberId: ID!): DeleteOrganisationMemberMutation updateOrganisationMemberRole(memberId: ID!, roleId: ID!): UpdateOrganisationMemberRole - updateMemberWrappedSecrets( - orgId: ID! - wrappedKeyring: String! - wrappedRecovery: String! - ): UpdateUserWrappedSecretsMutation + updateMemberWrappedSecrets(orgId: ID!, wrappedKeyring: String!, wrappedRecovery: String!): UpdateUserWrappedSecretsMutation deleteInvitation(inviteId: ID!): DeleteInviteMutation - createApp( - appSeed: String! - appToken: String! - appVersion: Int! - id: ID! - identityKey: String! - name: String! - organisationId: ID! - wrappedKeyShare: String! - ): CreateAppMutation + createApp(appSeed: String!, appToken: String!, appVersion: Int!, id: ID!, identityKey: String!, name: String!, organisationId: ID!, wrappedKeyShare: String!): CreateAppMutation rotateAppKeys(appToken: String!, id: ID!, wrappedKeyShare: String!): RotateAppKeysMutation deleteApp(id: ID!): DeleteAppMutation updateAppName(id: ID!, name: String!): UpdateAppNameMutation - addAppMember( - appId: ID - envKeys: [EnvironmentKeyInput] - memberId: ID - memberType: MemberType - ): AddAppMemberMutation + addAppMember(appId: ID, envKeys: [EnvironmentKeyInput], memberId: ID, memberType: MemberType): AddAppMemberMutation bulkAddAppMembers(appId: ID!, members: [AppMemberInputType]!): BulkAddAppMembersMutation removeAppMember(appId: ID, memberId: ID, memberType: MemberType): RemoveAppMemberMutation - updateMemberEnvironmentScope( - appId: ID - envKeys: [EnvironmentKeyInput] - memberId: ID - memberType: MemberType - ): UpdateMemberEnvScopeMutation - createEnvironment( - adminKeys: [EnvironmentKeyInput] - environmentData: EnvironmentInput! - wrappedSalt: String - wrappedSeed: String - ): CreateEnvironmentMutation + updateMemberEnvironmentScope(appId: ID, envKeys: [EnvironmentKeyInput], memberId: ID, memberType: MemberType): UpdateMemberEnvScopeMutation + createEnvironment(adminKeys: [EnvironmentKeyInput], environmentData: EnvironmentInput!, wrappedSalt: String, wrappedSeed: String): CreateEnvironmentMutation deleteEnvironment(environmentId: ID!): DeleteEnvironmentMutation renameEnvironment(environmentId: ID!, name: String!): RenameEnvironmentMutation swapEnvironmentOrder(environment1Id: ID!, environment2Id: ID!): SwapEnvironmentOrderMutation - createEnvironmentKey( - envId: ID! - identityKey: String! - userId: ID - wrappedSalt: String! - wrappedSeed: String! - ): CreateEnvironmentKeyMutation - createEnvironmentToken( - envId: ID! - identityKey: String! - name: String! - token: String! - wrappedKeyShare: String! - ): CreateEnvironmentTokenMutation - createCustomRole( - color: String - description: String - name: String - organisationId: ID! - permissions: JSONString - ): CreateCustomRoleMutation - updateCustomRole( - color: String - description: String - id: ID! - name: String - permissions: JSONString - ): UpdateCustomRoleMutation + createEnvironmentKey(envId: ID!, identityKey: String!, userId: ID, wrappedSalt: String!, wrappedSeed: String!): CreateEnvironmentKeyMutation + createEnvironmentToken(envId: ID!, identityKey: String!, name: String!, token: String!, wrappedKeyShare: String!): CreateEnvironmentTokenMutation + createCustomRole(color: String, description: String, name: String, organisationId: ID!, permissions: JSONString): CreateCustomRoleMutation + updateCustomRole(color: String, description: String, id: ID!, name: String, permissions: JSONString): UpdateCustomRoleMutation deleteCustomRole(id: ID!): DeleteCustomRoleMutation - createNetworkAccessPolicy( - allowedIps: String! - isGlobal: Boolean! - name: String - organisationId: ID! - ): CreateNetworkAccessPolicyMutation + createNetworkAccessPolicy(allowedIps: String!, isGlobal: Boolean!, name: String, organisationId: ID!): CreateNetworkAccessPolicyMutation updateNetworkAccessPolicy(policyInputs: [UpdatePolicyInput]): UpdateNetworkAccessPolicyMutation deleteNetworkAccessPolicy(id: ID!): DeleteNetworkAccessPolicyMutation - updateAccountNetworkAccessPolicies( - accountInputs: [AccountPolicyInput] - organisationId: ID! - ): UpdateAccountNetworkAccessPolicies - createServiceAccount( - handlers: [ServiceAccountHandlerInput] - identityKey: String - name: String - organisationId: ID - roleId: ID - serverWrappedKeyring: String - serverWrappedRecovery: String - ): CreateServiceAccountMutation - enableServiceAccountThirdPartyAuth( - serverWrappedKeyring: String - serverWrappedRecovery: String - serviceAccountId: ID - ): EnableServiceAccountThirdPartyAuthMutation - updateServiceAccountHandlers( - handlers: [ServiceAccountHandlerInput] - organisationId: ID - ): UpdateServiceAccountHandlersMutation + updateAccountNetworkAccessPolicies(accountInputs: [AccountPolicyInput], organisationId: ID!): UpdateAccountNetworkAccessPolicies + createServiceAccount(handlers: [ServiceAccountHandlerInput], identityKey: String, name: String, organisationId: ID, roleId: ID, serverWrappedKeyring: String, serverWrappedRecovery: String): CreateServiceAccountMutation + enableServiceAccountThirdPartyAuth(serverWrappedKeyring: String, serverWrappedRecovery: String, serviceAccountId: ID): EnableServiceAccountThirdPartyAuthMutation + updateServiceAccountHandlers(handlers: [ServiceAccountHandlerInput], organisationId: ID): UpdateServiceAccountHandlersMutation updateServiceAccount(name: String, roleId: ID, serviceAccountId: ID): UpdateServiceAccountMutation deleteServiceAccount(serviceAccountId: ID): DeleteServiceAccountMutation - createServiceAccountToken( - expiry: BigInt - identityKey: String! - name: String! - serviceAccountId: ID - token: String! - wrappedKeyShare: String! - ): CreateServiceAccountTokenMutation + createServiceAccountToken(expiry: BigInt, identityKey: String!, name: String!, serviceAccountId: ID, token: String!, wrappedKeyShare: String!): CreateServiceAccountTokenMutation deleteServiceAccountToken(tokenId: ID): DeleteServiceAccountTokenMutation initEnvSync(appId: ID, envKeys: [EnvironmentKeyInput]): InitEnvSync deleteEnvSync(syncId: ID): DeleteSync triggerSync(syncId: ID): TriggerSync toggleSyncActive(syncId: ID): ToggleSyncActive updateSyncAuthentication(credentialId: ID, syncId: ID): UpdateSyncAuthentication - createProviderCredentials( - credentials: JSONString - name: String - orgId: ID - provider: String - ): CreateProviderCredentials - updateProviderCredentials( - credentialId: ID - credentials: JSONString - name: String - ): UpdateProviderCredentials + createProviderCredentials(credentials: JSONString, name: String, orgId: ID, provider: String): CreateProviderCredentials + updateProviderCredentials(credentialId: ID, credentials: JSONString, name: String): UpdateProviderCredentials deleteProviderCredentials(credentialId: ID): DeleteProviderCredentials - createCloudflarePagesSync( - credentialId: ID - deploymentId: ID - envId: ID - path: String - projectEnv: String - projectName: String - ): CreateCloudflarePagesSync - createCloudflareWorkersSync( - credentialId: ID - envId: ID - path: String - workerName: String - ): CreateCloudflareWorkersSync - createAwsSecretSync( - credentialId: ID - envId: ID - kmsId: String - path: String - secretName: String - ): CreateAWSSecretsManagerSync - createGhActionsSync( - credentialId: ID - envId: ID - owner: String - path: String - repoName: String - ): CreateGitHubActionsSync - createVaultSync( - credentialId: ID - engine: String - envId: ID - path: String - vaultPath: String - ): CreateVaultSync - createNomadSync( - credentialId: ID - envId: ID - nomadNamespace: String - nomadPath: String - path: String - ): CreateNomadSync - createGitlabCiSync( - credentialId: ID - envId: ID - isGroup: Boolean - masked: Boolean - path: String - protected: Boolean - resourceId: String - resourcePath: String - ): CreateGitLabCISync - createRailwaySync( - credentialId: ID - envId: ID - path: String - railwayEnvironment: RailwayResourceInput - railwayProject: RailwayResourceInput - railwayService: RailwayResourceInput - ): CreateRailwaySync - createVercelSync( - credentialId: ID - envId: ID - environment: String - path: String - projectId: String - projectName: String - secretType: String - teamId: String - teamName: String - ): CreateVercelSync - createRenderSync( - credentialId: ID - envId: ID - path: String - resourceId: String - resourceName: String - resourceType: RenderResourceType - secretFileName: String - ): CreateRenderSync - createUserToken( - expiry: BigInt - identityKey: String! - name: String! - orgId: ID! - token: String! - wrappedKeyShare: String! - ): CreateUserTokenMutation + createCloudflarePagesSync(credentialId: ID, deploymentId: ID, envId: ID, path: String, projectEnv: String, projectName: String): CreateCloudflarePagesSync + createCloudflareWorkersSync(credentialId: ID, envId: ID, path: String, workerName: String): CreateCloudflareWorkersSync + createAwsSecretSync(credentialId: ID, envId: ID, kmsId: String, path: String, secretName: String): CreateAWSSecretsManagerSync + createGhActionsSync(credentialId: ID, envId: ID, environmentName: String, owner: String, path: String, repoName: String): CreateGitHubActionsSync + createVaultSync(credentialId: ID, engine: String, envId: ID, path: String, vaultPath: String): CreateVaultSync + createNomadSync(credentialId: ID, envId: ID, nomadNamespace: String, nomadPath: String, path: String): CreateNomadSync + createGitlabCiSync(credentialId: ID, envId: ID, isGroup: Boolean, masked: Boolean, path: String, protected: Boolean, resourceId: String, resourcePath: String): CreateGitLabCISync + createRailwaySync(credentialId: ID, envId: ID, path: String, railwayEnvironment: RailwayResourceInput, railwayProject: RailwayResourceInput, railwayService: RailwayResourceInput): CreateRailwaySync + createVercelSync(credentialId: ID, envId: ID, environment: String, path: String, projectId: String, projectName: String, secretType: String, teamId: String, teamName: String): CreateVercelSync + createRenderSync(credentialId: ID, envId: ID, path: String, resourceId: String, resourceName: String, resourceType: RenderResourceType, secretFileName: String): CreateRenderSync + createUserToken(expiry: BigInt, identityKey: String!, name: String!, orgId: ID!, token: String!, wrappedKeyShare: String!): CreateUserTokenMutation deleteUserToken(tokenId: ID!): DeleteUserTokenMutation - createServiceToken( - appId: ID! - environmentKeys: [EnvironmentKeyInput] - expiry: BigInt - identityKey: String! - name: String! - token: String! - wrappedKeyShare: String! - ): CreateServiceTokenMutation + createServiceToken(appId: ID!, environmentKeys: [EnvironmentKeyInput], expiry: BigInt, identityKey: String!, name: String!, token: String!, wrappedKeyShare: String!): CreateServiceTokenMutation deleteServiceToken(tokenId: ID!): DeleteServiceTokenMutation createSecretFolder(envId: ID, name: String, path: String): CreateSecretFolderMutation deleteSecretFolder(folderId: ID): DeleteSecretFolderMutation @@ -1260,53 +975,20 @@ type Mutation { createOverride(overrideData: PersonalSecretInput): CreatePersonalSecretMutation removeOverride(secretId: ID): DeletePersonalSecretMutation createLockbox(input: LockboxInput): CreateLockboxMutation - createSubscriptionCheckoutSession( - billingPeriod: BillingPeriodEnum - organisationId: ID! - planType: PlanTypeEnum - ): CreateSubscriptionCheckoutSession + createSubscriptionCheckoutSession(billingPeriod: BillingPeriodEnum, organisationId: ID!, planType: PlanTypeEnum): CreateSubscriptionCheckoutSession deletePaymentMethod(organisationId: ID, paymentMethodId: String): DeletePaymentMethodMutation cancelSubscription(organisationId: ID, subscriptionId: String!): UpdateSubscriptionResponse resumeSubscription(organisationId: ID, subscriptionId: String!): UpdateSubscriptionResponse - modifySubscription( - billingPeriod: BillingPeriodEnum - organisationId: ID! - planType: PlanTypeEnum - subscriptionId: String! - ): UpdateSubscriptionResponse + modifySubscription(billingPeriod: BillingPeriodEnum, organisationId: ID!, planType: PlanTypeEnum, subscriptionId: String!): UpdateSubscriptionResponse createSetupIntent(organisationId: ID): CreateSetupIntentMutation setDefaultPaymentMethod( organisationId: ID - """ - Payment Method ID to set as default - """ + """Payment Method ID to set as default""" paymentMethodId: String! ): SetDefaultPaymentMethodMutation - createAwsDynamicSecret( - authenticationId: ID - config: AWSConfigInput! - defaultTtl: Int - description: String - environmentId: ID! - keyMap: [KeyMapInput]! - maxTtl: Int - name: String! - organisationId: ID! - path: String - ): CreateAWSDynamicSecretMutation - updateAwsDynamicSecret( - authenticationId: ID - config: AWSConfigInput! - defaultTtl: Int - description: String - dynamicSecretId: ID! - keyMap: [KeyMapInput]! - maxTtl: Int - name: String! - organisationId: ID! - path: String - ): UpdateAWSDynamicSecretMutation + createAwsDynamicSecret(authenticationId: ID, config: AWSConfigInput!, defaultTtl: Int, description: String, environmentId: ID!, keyMap: [KeyMapInput]!, maxTtl: Int, name: String!, organisationId: ID!, path: String): CreateAWSDynamicSecretMutation + updateAwsDynamicSecret(authenticationId: ID, config: AWSConfigInput!, defaultTtl: Int, description: String, dynamicSecretId: ID!, keyMap: [KeyMapInput]!, maxTtl: Int, name: String!, organisationId: ID!, path: String): UpdateAWSDynamicSecretMutation deleteDynamicSecret(secretId: ID!): DeleteDynamicSecretMutation createDynamicSecretLease(name: String, secretId: ID!, ttl: Int): LeaseDynamicSecret renewDynamicSecretLease(leaseId: ID!, ttl: Int): RenewLeaseMutation From 9afd724461840419b15e19d5bceb770734844e7f Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:40:25 +0530 Subject: [PATCH 07/12] feat: enhance GitHub actions sync mutation by adding optional environment name parameter and implement query for fetching GitHub environments --- frontend/apollo/gql.ts | 9 +++++++-- frontend/apollo/graphql.ts | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/frontend/apollo/gql.ts b/frontend/apollo/gql.ts index b4c16e884..4312bddf3 100644 --- a/frontend/apollo/gql.ts +++ b/frontend/apollo/gql.ts @@ -79,7 +79,7 @@ const documents = { "mutation CreateNewCfWorkersSync($envId: ID!, $path: String!, $workerName: String!, $credentialId: ID!) {\n createCloudflareWorkersSync(\n envId: $envId\n path: $path\n workerName: $workerName\n credentialId: $credentialId\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}": types.CreateNewCfWorkersSyncDocument, "mutation DeleteProviderCreds($credentialId: ID!) {\n deleteProviderCredentials(credentialId: $credentialId) {\n ok\n }\n}": types.DeleteProviderCredsDocument, "mutation DeleteSync($syncId: ID!) {\n deleteEnvSync(syncId: $syncId) {\n ok\n }\n}": types.DeleteSyncDocument, - "mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!) {\n createGhActionsSync(\n envId: $envId\n path: $path\n repoName: $repoName\n owner: $owner\n credentialId: $credentialId\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}": types.CreateNewGhActionsSyncDocument, + "mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!, $environmentName: String) {\n createGhActionsSync(\n envId: $envId\n path: $path\n repoName: $repoName\n owner: $owner\n credentialId: $credentialId\n environmentName: $environmentName\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}": types.CreateNewGhActionsSyncDocument, "mutation CreateNewGitlabCiSync($envId: ID!, $path: String!, $credentialId: ID!, $resourcePath: String!, $resourceId: String!, $isGroup: Boolean!, $isMasked: Boolean!, $isProtected: Boolean!) {\n createGitlabCiSync(\n envId: $envId\n path: $path\n credentialId: $credentialId\n resourcePath: $resourcePath\n resourceId: $resourceId\n isGroup: $isGroup\n masked: $isMasked\n protected: $isProtected\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}": types.CreateNewGitlabCiSyncDocument, "mutation InitAppSyncing($appId: ID!, $envKeys: [EnvironmentKeyInput]) {\n initEnvSync(appId: $appId, envKeys: $envKeys) {\n app {\n id\n sseEnabled\n }\n }\n}": types.InitAppSyncingDocument, "mutation CreateNewNomadSync($envId: ID!, $path: String!, $nomadPath: String!, $nomadNamespace: String!, $credentialId: ID!) {\n createNomadSync(\n envId: $envId\n path: $path\n nomadPath: $nomadPath\n nomadNamespace: $nomadNamespace\n credentialId: $credentialId\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}": types.CreateNewNomadSyncDocument, @@ -147,6 +147,7 @@ const documents = { "query GetSavedCredentials($orgId: ID!) {\n savedCredentials(orgId: $orgId) {\n id\n name\n credentials\n createdAt\n provider {\n id\n name\n expectedCredentials\n optionalCredentials\n }\n syncCount\n }\n}": types.GetSavedCredentialsDocument, "query GetServerKey {\n serverPublicKey\n}": types.GetServerKeyDocument, "query GetServiceList {\n services {\n id\n name\n provider {\n id\n }\n }\n}": types.GetServiceListDocument, + "query GetGithubEnvironments($credentialId: ID!, $owner: String!, $repoName: String!) {\n githubEnvironments(\n credentialId: $credentialId\n owner: $owner\n repoName: $repoName\n )\n}": types.GetGithubEnvironmentsDocument, "query GetGithubRepos($credentialId: ID!) {\n githubRepos(credentialId: $credentialId) {\n name\n owner\n type\n }\n}": types.GetGithubReposDocument, "query GetGitLabResources($credentialId: ID!) {\n gitlabProjects(credentialId: $credentialId) {\n id\n name\n namespace {\n name\n fullPath\n }\n pathWithNamespace\n webUrl\n }\n gitlabGroups(credentialId: $credentialId) {\n id\n fullName\n fullPath\n webUrl\n }\n}": types.GetGitLabResourcesDocument, "query TestNomadAuth($credentialId: ID!) {\n testNomadCreds(credentialId: $credentialId)\n}": types.TestNomadAuthDocument, @@ -439,7 +440,7 @@ export function graphql(source: "mutation DeleteSync($syncId: ID!) {\n deleteEn /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!) {\n createGhActionsSync(\n envId: $envId\n path: $path\n repoName: $repoName\n owner: $owner\n credentialId: $credentialId\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}"): (typeof documents)["mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!) {\n createGhActionsSync(\n envId: $envId\n path: $path\n repoName: $repoName\n owner: $owner\n credentialId: $credentialId\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}"]; +export function graphql(source: "mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!, $environmentName: String) {\n createGhActionsSync(\n envId: $envId\n path: $path\n repoName: $repoName\n owner: $owner\n credentialId: $credentialId\n environmentName: $environmentName\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}"): (typeof documents)["mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!, $environmentName: String) {\n createGhActionsSync(\n envId: $envId\n path: $path\n repoName: $repoName\n owner: $owner\n credentialId: $credentialId\n environmentName: $environmentName\n ) {\n sync {\n id\n environment {\n id\n name\n envType\n }\n serviceInfo {\n id\n name\n }\n isActive\n lastSync\n createdAt\n }\n }\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -708,6 +709,10 @@ export function graphql(source: "query GetServerKey {\n serverPublicKey\n}"): ( * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "query GetServiceList {\n services {\n id\n name\n provider {\n id\n }\n }\n}"): (typeof documents)["query GetServiceList {\n services {\n id\n name\n provider {\n id\n }\n }\n}"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "query GetGithubEnvironments($credentialId: ID!, $owner: String!, $repoName: String!) {\n githubEnvironments(\n credentialId: $credentialId\n owner: $owner\n repoName: $repoName\n )\n}"): (typeof documents)["query GetGithubEnvironments($credentialId: ID!, $owner: String!, $repoName: String!) {\n githubEnvironments(\n credentialId: $credentialId\n owner: $owner\n repoName: $repoName\n )\n}"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/frontend/apollo/graphql.ts b/frontend/apollo/graphql.ts index 42c091cb2..3ba39bed2 100644 --- a/frontend/apollo/graphql.ts +++ b/frontend/apollo/graphql.ts @@ -1052,6 +1052,7 @@ export type MutationCreateEnvironmentTokenArgs = { export type MutationCreateGhActionsSyncArgs = { credentialId?: InputMaybe; envId?: InputMaybe; + environmentName?: InputMaybe; owner?: InputMaybe; path?: InputMaybe; repoName?: InputMaybe; @@ -1698,6 +1699,7 @@ export type Query = { environmentKeys?: Maybe>>; environmentTokens?: Maybe>>; folders?: Maybe>>; + githubEnvironments?: Maybe>>; githubRepos?: Maybe>>; gitlabGroups?: Maybe>>; gitlabProjects?: Maybe>>; @@ -1819,6 +1821,13 @@ export type QueryFoldersArgs = { }; +export type QueryGithubEnvironmentsArgs = { + credentialId?: InputMaybe; + owner?: InputMaybe; + repoName?: InputMaybe; +}; + + export type QueryGithubReposArgs = { credentialId?: InputMaybe; }; @@ -3019,6 +3028,7 @@ export type CreateNewGhActionsSyncMutationVariables = Exact<{ repoName: Scalars['String']['input']; owner: Scalars['String']['input']; credentialId: Scalars['ID']['input']; + environmentName?: InputMaybe; }>; @@ -3555,6 +3565,15 @@ export type GetServiceListQueryVariables = Exact<{ [key: string]: never; }>; export type GetServiceListQuery = { __typename?: 'Query', services?: Array<{ __typename?: 'ServiceType', id?: string | null, name?: string | null, provider?: { __typename?: 'ProviderType', id: string } | null } | null> | null }; +export type GetGithubEnvironmentsQueryVariables = Exact<{ + credentialId: Scalars['ID']['input']; + owner: Scalars['String']['input']; + repoName: Scalars['String']['input']; +}>; + + +export type GetGithubEnvironmentsQuery = { __typename?: 'Query', githubEnvironments?: Array | null }; + export type GetGithubReposQueryVariables = Exact<{ credentialId: Scalars['ID']['input']; }>; @@ -3686,7 +3705,7 @@ export const CreateNewCfPagesSyncDocument = {"kind":"Document","definitions":[{" export const CreateNewCfWorkersSyncDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateNewCfWorkersSync"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"workerName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createCloudflareWorkersSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}},{"kind":"Argument","name":{"kind":"Name","value":"workerName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"workerName"}}},{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sync"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"lastSync"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; export const DeleteProviderCredsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteProviderCreds"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteProviderCredentials"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ok"}}]}}]}}]} as unknown as DocumentNode; export const DeleteSyncDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteSync"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"syncId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteEnvSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"syncId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ok"}}]}}]}}]} as unknown as DocumentNode; -export const CreateNewGhActionsSyncDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateNewGhActionsSync"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"repoName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"owner"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createGhActionsSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}},{"kind":"Argument","name":{"kind":"Name","value":"repoName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"repoName"}}},{"kind":"Argument","name":{"kind":"Name","value":"owner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"owner"}}},{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sync"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"lastSync"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; +export const CreateNewGhActionsSyncDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateNewGhActionsSync"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"repoName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"owner"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"environmentName"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createGhActionsSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}},{"kind":"Argument","name":{"kind":"Name","value":"repoName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"repoName"}}},{"kind":"Argument","name":{"kind":"Name","value":"owner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"owner"}}},{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}},{"kind":"Argument","name":{"kind":"Name","value":"environmentName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"environmentName"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sync"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"lastSync"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateNewGitlabCiSyncDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateNewGitlabCiSync"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"resourcePath"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"resourceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"isGroup"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"isMasked"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"isProtected"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createGitlabCiSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}},{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}},{"kind":"Argument","name":{"kind":"Name","value":"resourcePath"},"value":{"kind":"Variable","name":{"kind":"Name","value":"resourcePath"}}},{"kind":"Argument","name":{"kind":"Name","value":"resourceId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"resourceId"}}},{"kind":"Argument","name":{"kind":"Name","value":"isGroup"},"value":{"kind":"Variable","name":{"kind":"Name","value":"isGroup"}}},{"kind":"Argument","name":{"kind":"Name","value":"masked"},"value":{"kind":"Variable","name":{"kind":"Name","value":"isMasked"}}},{"kind":"Argument","name":{"kind":"Name","value":"protected"},"value":{"kind":"Variable","name":{"kind":"Name","value":"isProtected"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sync"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"lastSync"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; export const InitAppSyncingDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InitAppSyncing"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envKeys"}},"type":{"kind":"ListType","type":{"kind":"NamedType","name":{"kind":"Name","value":"EnvironmentKeyInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"initEnvSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appId"}}},{"kind":"Argument","name":{"kind":"Name","value":"envKeys"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envKeys"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"app"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"sseEnabled"}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateNewNomadSyncDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateNewNomadSync"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"envId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"nomadPath"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"nomadNamespace"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createNomadSync"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"envId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"envId"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}},{"kind":"Argument","name":{"kind":"Name","value":"nomadPath"},"value":{"kind":"Variable","name":{"kind":"Name","value":"nomadPath"}}},{"kind":"Argument","name":{"kind":"Name","value":"nomadNamespace"},"value":{"kind":"Variable","name":{"kind":"Name","value":"nomadNamespace"}}},{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sync"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"environment"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"envType"}}]}},{"kind":"Field","name":{"kind":"Name","value":"serviceInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"lastSync"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; @@ -3754,6 +3773,7 @@ export const GetProviderListDocument = {"kind":"Document","definitions":[{"kind" export const GetSavedCredentialsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSavedCredentials"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"savedCredentials"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orgId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orgId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"credentials"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"provider"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"expectedCredentials"}},{"kind":"Field","name":{"kind":"Name","value":"optionalCredentials"}}]}},{"kind":"Field","name":{"kind":"Name","value":"syncCount"}}]}}]}}]} as unknown as DocumentNode; export const GetServerKeyDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetServerKey"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"serverPublicKey"}}]}}]} as unknown as DocumentNode; export const GetServiceListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetServiceList"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"services"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"provider"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; +export const GetGithubEnvironmentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetGithubEnvironments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"owner"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"repoName"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"githubEnvironments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}},{"kind":"Argument","name":{"kind":"Name","value":"owner"},"value":{"kind":"Variable","name":{"kind":"Name","value":"owner"}}},{"kind":"Argument","name":{"kind":"Name","value":"repoName"},"value":{"kind":"Variable","name":{"kind":"Name","value":"repoName"}}}]}]}}]} as unknown as DocumentNode; export const GetGithubReposDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetGithubRepos"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"githubRepos"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"owner"}},{"kind":"Field","name":{"kind":"Name","value":"type"}}]}}]}}]} as unknown as DocumentNode; export const GetGitLabResourcesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetGitLabResources"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"gitlabProjects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"namespace"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"fullPath"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pathWithNamespace"}},{"kind":"Field","name":{"kind":"Name","value":"webUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"gitlabGroups"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"fullName"}},{"kind":"Field","name":{"kind":"Name","value":"fullPath"}},{"kind":"Field","name":{"kind":"Name","value":"webUrl"}}]}}]}}]} as unknown as DocumentNode; export const TestNomadAuthDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"TestNomadAuth"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"testNomadCreds"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"credentialId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"credentialId"}}}]}]}}]} as unknown as DocumentNode; From 7e91380daf76a6bfe70fcedef01eca8d1f1733ee Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:40:55 +0530 Subject: [PATCH 08/12] feat: enhance GitHub service info display by adding optional environment name to the component --- frontend/components/syncing/ServiceInfo.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/components/syncing/ServiceInfo.tsx b/frontend/components/syncing/ServiceInfo.tsx index b3f115988..1afe11a62 100644 --- a/frontend/components/syncing/ServiceInfo.tsx +++ b/frontend/components/syncing/ServiceInfo.tsx @@ -20,12 +20,15 @@ export const ServiceInfo = (props: { sync: EnvironmentSyncType }) => { return
{secretName}
} else if (sync.serviceInfo?.id?.includes('github')) { - const repoName = JSON.parse(sync.options)['repo_name'] - const owner = JSON.parse(sync.options)['owner'] + const ghSyncMeta = JSON.parse(sync.options) + const repoName = ghSyncMeta['repo_name'] + const owner = ghSyncMeta['owner'] + const ghEnv = ghSyncMeta['environment_name'] return (
{owner}/{repoName} + {ghEnv && ({ghEnv})}
) } else if (sync.serviceInfo?.id?.includes('hashicorp_vault')) { From 4eb35bfd7ee8b22ce91d22192b0420476cc680f4 Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:41:14 +0530 Subject: [PATCH 09/12] feat: implement loading of GitHub environments based on selected repository and enhance UI for environment selection --- .../syncing/GitHub/CreateGhActionsSync.tsx | 117 +++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/frontend/components/syncing/GitHub/CreateGhActionsSync.tsx b/frontend/components/syncing/GitHub/CreateGhActionsSync.tsx index 8ef0147db..d411c1915 100644 --- a/frontend/components/syncing/GitHub/CreateGhActionsSync.tsx +++ b/frontend/components/syncing/GitHub/CreateGhActionsSync.tsx @@ -3,6 +3,7 @@ import GetAppSyncStatus from '@/graphql/queries/syncing/getAppSyncStatus.gql' import GetAppEnvironments from '@/graphql/queries/secrets/getAppEnvironments.gql' import GetSavedCredentials from '@/graphql/queries/syncing/getSavedCredentials.gql' import CreateNewGhActionsSync from '@/graphql/mutations/syncing/github/CreateGhActionsSync.gql' +import GetGithubEnvironments from '@/graphql/queries/syncing/github/getEnvironments.gql' import { useLazyQuery, useMutation, useQuery } from '@apollo/client' import { Fragment, useContext, useEffect, useState } from 'react' import { Button } from '../../common/Button' @@ -38,6 +39,7 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo }) const [getGhRepos, { loading }] = useLazyQuery(GetGithubRepos) + const [getGhEnvironments] = useLazyQuery(GetGithubEnvironments) const [createGhActionsSync, { data: syncData, loading: creating }] = useMutation(CreateNewGhActionsSync) @@ -45,9 +47,12 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo const [credential, setCredential] = useState(null) const [repos, setRepos] = useState([]) + const [environments, setEnvironments] = useState([]) const [selectedRepo, setSelectedRepo] = useState(undefined) + const [selectedEnvironment, setSelectedEnvironment] = useState(undefined) const [query, setQuery] = useState('') + const [envQuery, setEnvQuery] = useState('') const [phaseEnv, setPhaseEnv] = useState(null) const [path, setPath] = useState('/') @@ -68,6 +73,26 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo } }, [appEnvsData]) + // Load environments for selected repo when repo changes + useEffect(() => { + const loadEnvs = async () => { + if (!credential || !selectedRepo) return + const { data } = await getGhEnvironments({ + variables: { + credentialId: credential.id, + owner: selectedRepo.owner, + repoName: selectedRepo.name, + }, + }) + if (data?.githubEnvironments) { + setEnvironments(data.githubEnvironments) + } else { + setEnvironments([]) + } + } + loadEnvs() + }, [credential, selectedRepo, getGhEnvironments]) + const handleSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault() @@ -95,6 +120,7 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo repoName: selectedRepo.name, owner: selectedRepo.owner, credentialId: credential.id, + environmentName: selectedEnvironment || null, }, refetchQueries: [{ query: GetAppSyncStatus, variables: { appId } }], }) @@ -192,7 +218,7 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo
@@ -274,6 +300,95 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo )}
+
+ + {({ open }) => ( + <> +
+ + + +
+ setEnvQuery(e.target.value)} + displayValue={(env?: string) => (env ? env : envQuery)} + aria-disabled={!selectedRepo} + placeholder={ + !selectedRepo + ? 'Select a repository' + : environments.length === 0 + ? 'No environments found' + : 'Select an environment' + } + /> +
+ + + +
+
+
+ {selectedRepo && ( + + +
+ + {({ active, selected }) => ( +
+
No environment (repo-level)
+ {selected && } +
+ )} +
+ {environments + .filter((env) => (envQuery ? env.toLowerCase().includes(envQuery.toLowerCase()) : true)) + .map((env) => ( + + {({ active, selected }) => ( +
+
{env}
+ {selected && } +
+ )} +
+ ))} +
+
+
+ )} + + )} +
+
)} From 51190b2f921572410011cf0c822ae20949606152 Mon Sep 17 00:00:00 2001 From: Nimish Date: Thu, 2 Oct 2025 12:41:33 +0530 Subject: [PATCH 10/12] feat: update GitHub actions sync mutation to include optional environment name and add query for fetching GitHub environments --- .../graphql/mutations/syncing/github/CreateGhActionsSync.gql | 4 ++-- frontend/graphql/queries/syncing/github/getEnvironments.gql | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 frontend/graphql/queries/syncing/github/getEnvironments.gql diff --git a/frontend/graphql/mutations/syncing/github/CreateGhActionsSync.gql b/frontend/graphql/mutations/syncing/github/CreateGhActionsSync.gql index f48e5e85b..ba487e5b3 100644 --- a/frontend/graphql/mutations/syncing/github/CreateGhActionsSync.gql +++ b/frontend/graphql/mutations/syncing/github/CreateGhActionsSync.gql @@ -1,5 +1,5 @@ -mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!) { - createGhActionsSync(envId: $envId, path: $path, repoName: $repoName, owner: $owner, credentialId: $credentialId) { +mutation CreateNewGhActionsSync($envId: ID!, $path: String!, $repoName: String!, $owner: String!, $credentialId: ID!, $environmentName: String) { + createGhActionsSync(envId: $envId, path: $path, repoName: $repoName, owner: $owner, credentialId: $credentialId, environmentName: $environmentName) { sync { id environment { diff --git a/frontend/graphql/queries/syncing/github/getEnvironments.gql b/frontend/graphql/queries/syncing/github/getEnvironments.gql new file mode 100644 index 000000000..7a95b7727 --- /dev/null +++ b/frontend/graphql/queries/syncing/github/getEnvironments.gql @@ -0,0 +1,3 @@ +query GetGithubEnvironments($credentialId: ID!, $owner: String!, $repoName: String!) { + githubEnvironments(credentialId: $credentialId, owner: $owner, repoName: $repoName) +} From 0b22997a6f99aaef49cb0f6681f9947843de815c Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 6 Oct 2025 15:56:41 +0530 Subject: [PATCH 11/12] chore: regenerate schema Signed-off-by: rohan --- frontend/apollo/schema.graphql | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/apollo/schema.graphql b/frontend/apollo/schema.graphql index af914cc91..e87d120d1 100644 --- a/frontend/apollo/schema.graphql +++ b/frontend/apollo/schema.graphql @@ -970,13 +970,10 @@ type Mutation { updateNetworkAccessPolicy(policyInputs: [UpdatePolicyInput]): UpdateNetworkAccessPolicyMutation deleteNetworkAccessPolicy(id: ID!): DeleteNetworkAccessPolicyMutation updateAccountNetworkAccessPolicies(accountInputs: [AccountPolicyInput], organisationId: ID!): UpdateAccountNetworkAccessPolicies - createServiceAccount(handlers: [ServiceAccountHandlerInput], identityKey: String, name: String, organisationId: ID, roleId: ID, serverWrappedKeyring: String, serverWrappedRecovery: String): CreateServiceAccountMutation - enableServiceAccountThirdPartyAuth(serverWrappedKeyring: String, serverWrappedRecovery: String, serviceAccountId: ID): EnableServiceAccountThirdPartyAuthMutation - updateServiceAccountHandlers(handlers: [ServiceAccountHandlerInput], organisationId: ID): UpdateServiceAccountHandlersMutation - updateServiceAccount(name: String, roleId: ID, serviceAccountId: ID): UpdateServiceAccountMutation createIdentity(defaultTtlSeconds: Int!, description: String, maxTtlSeconds: Int!, name: String!, organisationId: ID!, provider: String!, signatureTtlSeconds: Int, stsEndpoint: String, tokenNamePattern: String, trustedPrincipals: String!): CreateIdentityMutation updateIdentity(defaultTtlSeconds: Int, description: String, id: ID!, maxTtlSeconds: Int, name: String, signatureTtlSeconds: Int, stsEndpoint: String, tokenNamePattern: String, trustedPrincipals: String): UpdateIdentityMutation deleteIdentity(id: ID!): DeleteIdentityMutation + createServiceAccount(handlers: [ServiceAccountHandlerInput], identityKey: String, name: String, organisationId: ID, roleId: ID, serverWrappedKeyring: String, serverWrappedRecovery: String): CreateServiceAccountMutation enableServiceAccountServerSideKeyManagement(serverWrappedKeyring: String, serverWrappedRecovery: String, serviceAccountId: ID): EnableServiceAccountServerSideKeyManagementMutation enableServiceAccountClientSideKeyManagement(serviceAccountId: ID): EnableServiceAccountClientSideKeyManagementMutation updateServiceAccountHandlers(handlers: [ServiceAccountHandlerInput], organisationId: ID): UpdateServiceAccountHandlersMutation From eec97532ad8ead36710aeb59cd8c0d75e939e8bb Mon Sep 17 00:00:00 2001 From: rohan Date: Mon, 6 Oct 2025 18:47:14 +0530 Subject: [PATCH 12/12] fix: remove unecessary useEffect, clean up padding Signed-off-by: rohan --- .../components/syncing/CreateSyncDialog.tsx | 2 +- .../syncing/GitHub/CreateGhActionsSync.tsx | 105 +++++++++--------- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/frontend/components/syncing/CreateSyncDialog.tsx b/frontend/components/syncing/CreateSyncDialog.tsx index 1f6aca927..87e8d74ea 100644 --- a/frontend/components/syncing/CreateSyncDialog.tsx +++ b/frontend/components/syncing/CreateSyncDialog.tsx @@ -116,7 +116,7 @@ export const CreateSyncDialog = (props: { {userCanReadEnvs && userCanCreateIntegrations ? ( -
{isOpen && renderSyncPanel(props.service)}
+
{isOpen && renderSyncPanel(props.service)}
) : ( vo const { appId, closeModal } = props - const { data: appEnvsData } = useQuery(GetAppEnvironments, { - variables: { - appId, - }, - }) - const { data: credentialsData } = useQuery(GetSavedCredentials, { - variables: { orgId: organisation!.id }, - }) - - const [getGhRepos, { loading }] = useLazyQuery(GetGithubRepos) - const [getGhEnvironments] = useLazyQuery(GetGithubEnvironments) - const [createGhActionsSync, { data: syncData, loading: creating }] = useMutation(CreateNewGhActionsSync) const [credential, setCredential] = useState(null) - const [repos, setRepos] = useState([]) - const [environments, setEnvironments] = useState([]) - const [selectedRepo, setSelectedRepo] = useState(undefined) const [selectedEnvironment, setSelectedEnvironment] = useState(undefined) const [query, setQuery] = useState('') const [envQuery, setEnvQuery] = useState('') + const [repos, setRepos] = useState([]) const [phaseEnv, setPhaseEnv] = useState(null) const [path, setPath] = useState('/') const [credentialsValid, setCredentialsValid] = useState(false) + const { data: appEnvsData } = useQuery(GetAppEnvironments, { + variables: { + appId, + }, + }) + const { data: credentialsData } = useQuery(GetSavedCredentials, { + variables: { orgId: organisation!.id }, + }) + + const [getGhRepos] = useLazyQuery(GetGithubRepos) + + const { data: environmentsData } = useQuery(GetGithubEnvironments, { + variables: { + credentialId: credential?.id, + owner: selectedRepo?.owner, + repoName: selectedRepo?.name, + }, + skip: !credential || !selectedRepo, // Only fetch when we have both credential and selected repo + }) + + const environments = environmentsData?.githubEnvironments || [] + useEffect(() => { if (credentialsData && credentialsData.savedCredentials.length > 0) { setCredential(credentialsData.savedCredentials[0]) @@ -73,26 +81,6 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo } }, [appEnvsData]) - // Load environments for selected repo when repo changes - useEffect(() => { - const loadEnvs = async () => { - if (!credential || !selectedRepo) return - const { data } = await getGhEnvironments({ - variables: { - credentialId: credential.id, - owner: selectedRepo.owner, - repoName: selectedRepo.name, - }, - }) - if (data?.githubEnvironments) { - setEnvironments(data.githubEnvironments) - } else { - setEnvironments([]) - } - } - loadEnvs() - }, [credential, selectedRepo, getGhEnvironments]) - const handleSubmit = async (e: { preventDefault: () => void }) => { e.preventDefault() @@ -142,7 +130,7 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo }) return ( -
+
@@ -311,19 +299,22 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo
- setEnvQuery(e.target.value)} - displayValue={(env?: string) => (env ? env : envQuery)} - aria-disabled={!selectedRepo} + setEnvQuery(e.target.value)} + displayValue={(env?: string) => (env ? env : envQuery)} + aria-disabled={!selectedRepo} placeholder={ !selectedRepo ? 'Select a repository' : environments.length === 0 - ? 'No environments found' - : 'Select an environment' + ? 'No environments found' + : 'Select an environment' } - /> + />
vo active && 'bg-zinc-300 dark:bg-zinc-700' )} > -
No environment (repo-level)
- {selected && } +
+ No environment (repo-level) +
+ {selected && ( + + )}
)} {environments - .filter((env) => (envQuery ? env.toLowerCase().includes(envQuery.toLowerCase()) : true)) - .map((env) => ( + .filter((env: string) => + envQuery + ? env.toLowerCase().includes(envQuery.toLowerCase()) + : true + ) + .map((env: string) => ( {({ active, selected }) => (
vo active && 'bg-zinc-300 dark:bg-zinc-700' )} > -
{env}
- {selected && } +
+ {env} +
+ {selected && ( + + )}
)}
@@ -400,7 +403,7 @@ export const CreateGhActionsSync = (props: { appId: string; closeModal: () => vo )}
-