Sync travis-ci

This commit is contained in:
Aashish-Upadhyay-101
2023-02-24 13:36:17 +05:45
parent 8bf8968588
commit 499323d0e3
4 changed files with 145 additions and 6 deletions
+38 -1
View File
@@ -13,12 +13,14 @@ import {
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO, INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI, INTEGRATION_CIRCLECI,
INTEGRATION_TRAVISCI,
INTEGRATION_HEROKU_API_URL, INTEGRATION_HEROKU_API_URL,
INTEGRATION_VERCEL_API_URL, INTEGRATION_VERCEL_API_URL,
INTEGRATION_NETLIFY_API_URL, INTEGRATION_NETLIFY_API_URL,
INTEGRATION_RENDER_API_URL, INTEGRATION_RENDER_API_URL,
INTEGRATION_FLYIO_API_URL, INTEGRATION_FLYIO_API_URL,
INTEGRATION_CIRCLECI_API_URL, INTEGRATION_CIRCLECI_API_URL,
INTEGRATION_TRAVISCI_API_URL,
} from "../variables"; } from "../variables";
/** /**
@@ -42,7 +44,7 @@ const getApps = async ({
owner?: string; owner?: string;
} }
let apps: App[]; let apps: App[] = [];
try { try {
switch (integrationAuth.integration) { switch (integrationAuth.integration) {
case INTEGRATION_AZURE_KEY_VAULT: case INTEGRATION_AZURE_KEY_VAULT:
@@ -90,6 +92,11 @@ const getApps = async ({
accessToken, accessToken,
}); });
break; break;
case INTEGRATION_TRAVISCI:
apps = await getAppsTravisCI({
accessToken,
})
break;
} }
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
@@ -369,4 +376,34 @@ const getAppsCircleCI = async ({ accessToken }: { accessToken: string }) => {
return apps; return apps;
}; };
const getAppsTravisCI = async ({ accessToken }: { accessToken: string }) => {
let apps: any;
try {
const res = (
await axios.get(
`${INTEGRATION_TRAVISCI_API_URL}/repos`,
{
headers: {
"Authorization": `token ${accessToken}`,
"Accept-Encoding": "application/json",
},
}
)
).data;
apps = res?.map((a: any) => {
return {
name: a?.slug?.split("/")[1],
appId: a?.id,
}
});
}catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to get TravisCI projects");
}
return apps;
}
export { getApps }; export { getApps };
+102
View File
@@ -23,12 +23,14 @@ import {
INTEGRATION_RENDER, INTEGRATION_RENDER,
INTEGRATION_FLYIO, INTEGRATION_FLYIO,
INTEGRATION_CIRCLECI, INTEGRATION_CIRCLECI,
INTEGRATION_TRAVISCI,
INTEGRATION_HEROKU_API_URL, INTEGRATION_HEROKU_API_URL,
INTEGRATION_VERCEL_API_URL, INTEGRATION_VERCEL_API_URL,
INTEGRATION_NETLIFY_API_URL, INTEGRATION_NETLIFY_API_URL,
INTEGRATION_RENDER_API_URL, INTEGRATION_RENDER_API_URL,
INTEGRATION_FLYIO_API_URL, INTEGRATION_FLYIO_API_URL,
INTEGRATION_CIRCLECI_API_URL, INTEGRATION_CIRCLECI_API_URL,
INTEGRATION_TRAVISCI_API_URL,
} from "../variables"; } from "../variables";
/** /**
@@ -128,6 +130,14 @@ const syncSecrets = async ({
secrets, secrets,
accessToken, accessToken,
}); });
break;
case INTEGRATION_TRAVISCI:
await syncSecretsTravisCI({
integration,
secrets,
accessToken,
});
break;
} }
} catch (err) { } catch (err) {
Sentry.setUser(null); Sentry.setUser(null);
@@ -1283,4 +1293,96 @@ const syncSecretsCircleCI = async ({
} }
}; };
/**
* Sync/push [secrets] to TravisCI project
* @param {Object} obj
* @param {IIntegration} obj.integration - integration details
* @param {Object} obj.secrets - secrets to push to integration (object where keys are secret keys and values are secret values)
* @param {String} obj.accessToken - access token for TravisCI integration
*/
const syncSecretsTravisCI = async ({
integration,
secrets,
accessToken,
}: {
integration: IIntegration;
secrets: any;
accessToken: string;
}) => {
try {
// get secrets from travis-ci
const getSecretsRes = (
await axios.get(
`${INTEGRATION_TRAVISCI_API_URL}/settings/env_vars?repository_id=${integration.appId}`,
{
headers: {
"Authorization": `token ${accessToken}`,
"Accept-Encoding": "application/json",
},
}
)
).data?.env_vars;
// add secrets
for (const key of Object.keys(secrets)) {
const existingSecret = getSecretsRes.find((s: any) => s.name == key);
if(!existingSecret){
await axios.post(
`${INTEGRATION_TRAVISCI_API_URL}/settings/env_vars?repository_id=${integration.appId}`,
{
env_var: {
name: key,
value: secrets[key],
}
},
{
headers: {
"Authorization": `token ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json",
},
}
)
}else { // update secret
await axios.patch(
`${INTEGRATION_TRAVISCI_API_URL}/settings/env_vars/${existingSecret.id}?repository_id=${existingSecret.repository_id}`,
{
env_var: {
name: key,
value: secrets[key],
}
},
{
headers: {
"Authorization": `token ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json",
},
}
)
}
}
// delete secret
for (const sec of getSecretsRes) {
if (!(sec.name in secrets)){
await axios.delete(
`${INTEGRATION_TRAVISCI_API_URL}/settings/env_vars/${sec.id}?repository_id=${sec.repository_id}`,
{
headers: {
"Authorization": `token ${accessToken}`,
"Content-Type": "application/json",
"Accept-Encoding": "application/json",
},
}
);
}
}
}catch (err) {
Sentry.setUser(null);
Sentry.captureException(err);
throw new Error("Failed to sync secrets to CircleCI");
}
}
export { syncSecrets }; export { syncSecrets };
@@ -11,7 +11,7 @@ import {
} from '../../../components/v2'; } from '../../../components/v2';
import saveIntegrationAccessToken from "../../api/integrations/saveIntegrationAccessToken"; import saveIntegrationAccessToken from "../../api/integrations/saveIntegrationAccessToken";
export default function CircleCICreateIntegrationPage() { export default function TravisCICreateIntegrationPage() {
const router = useRouter(); const router = useRouter();
const [apiKey, setApiKey] = useState(''); const [apiKey, setApiKey] = useState('');
const [apiKeyErrorText, setApiKeyErrorText] = useState(''); const [apiKeyErrorText, setApiKeyErrorText] = useState('');
@@ -49,7 +49,7 @@ export default function CircleCICreateIntegrationPage() {
<Card className="max-w-md p-8 rounded-md"> <Card className="max-w-md p-8 rounded-md">
<CardTitle className='text-center'>TravisCI Integration</CardTitle> <CardTitle className='text-center'>TravisCI Integration</CardTitle>
<FormControl <FormControl
label="CircleCI API Token" label="Travis API Token"
errorText={apiKeyErrorText} errorText={apiKeyErrorText}
isError={apiKeyErrorText !== '' ?? false} isError={apiKeyErrorText !== '' ?? false}
> >
@@ -72,6 +72,6 @@ export default function CircleCICreateIntegrationPage() {
) )
} }
CircleCICreateIntegrationPage.requireAuth = true; TravisCICreateIntegrationPage.requireAuth = true;
export const getServerSideProps = getTranslatedServerSideProps(['integrations']); export const getServerSideProps = getTranslatedServerSideProps(['integrations']);
@@ -15,7 +15,7 @@ import { useGetIntegrationAuthApps,useGetIntegrationAuthById } from '../../../ho
import { useGetWorkspaceById } from '../../../hooks/api/workspace'; import { useGetWorkspaceById } from '../../../hooks/api/workspace';
import createIntegration from "../../api/integrations/createIntegration"; import createIntegration from "../../api/integrations/createIntegration";
export default function CircleCICreateIntegrationPage() { export default function TravisCICreateIntegrationPage() {
const router = useRouter(); const router = useRouter();
const { integrationAuthId } = queryString.parse(router.asPath.split('?')[1]); const { integrationAuthId } = queryString.parse(router.asPath.split('?')[1]);
@@ -119,6 +119,6 @@ export default function CircleCICreateIntegrationPage() {
) : <div /> ) : <div />
} }
CircleCICreateIntegrationPage.requireAuth = true; TravisCICreateIntegrationPage.requireAuth = true;
export const getServerSideProps = getTranslatedServerSideProps(['integrations']); export const getServerSideProps = getTranslatedServerSideProps(['integrations']);