Skip to content

Commit cac8fac

Browse files
authored
Merge pull request #422 from snyk-tech-services/feat/archived-repos
feat: sync command archived repos support
2 parents 913efbb + e165a21 commit cac8fac

File tree

8 files changed

+171
-29
lines changed

8 files changed

+171
-29
lines changed

docs/sync.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- [File renamed/moves/deleted](#file-renamedmovesdeleted)
1313
- [node\_modules, tests \& fixtures](#node_modules-tests--fixtures)
1414
- [Detecting \& importing new files not already monitored in Snyk](#detecting--importing-new-files-not-already-monitored-in-snyk)
15+
- [Repository is archived](#repository-is-archived)
1516
- [Kick off sync](#kick-off-sync)
1617
- [1. Set the env vars](#1-set-the-env-vars)
1718
- [2. Download \& run](#2-download--run)
@@ -76,6 +77,9 @@ Any projects that were imported but match the default exclusions list (deemed to
7677
While analyzing each target known to Snyk any new Snyk supported files found in the repo that do not have a corresponding project in Snyk will be imported in batches. Any files matching the default or user provided `exclusionGlobs` will be ignored.
7778
If a file has a corresponding de-activated project in Snyk, it will not be brought in again. Activate manually or via API if it should be active.
7879

80+
## Repository is archived
81+
82+
If the repository is now marked as archived, all relevant Snyk projects will be de-activated.
7983
# Kick off sync
8084

8185
`sync` command will analyze existing projects & targets (repos) in Snyk organization and determine if any changes are needed.
@@ -155,3 +159,4 @@ Live mode:
155159
- Any organizations using a custom branch feature are currently not supported, `sync` will not continue.
156160
- Any organizations that previously used the custom feature flag should ideally delete all existing projects & re-import to restore the project names to standard format (do not include a branch in the project name). `sync` will work regardless but may cause confusion as the project name will reference a branch that is not likely to be the actual branch being tested.
157161
- It is not possible to know if a file was moved or renamed in the current implementation as it requires looking through commits history or using webhooks. It is also not currently possible to re-name projects in Snyk. In all cases projects will be deactivated and their replacement re-imported, creating a new projects with new history.
162+
- Deleted repos are not yet supported.

src/lib/source-handlers/github/get-repo-metadata.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ export async function getGithubRepoMetaData(
2929
branch: response.data.default_branch!,
3030
cloneUrl: response.data.clone_url!,
3131
sshUrl: response.data.ssh_url!,
32+
archived: response.data.archived!,
3233
};
3334
}

src/lib/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export interface RepoMetaData {
216216
branch: string;
217217
cloneUrl: string;
218218
sshUrl: string;
219+
archived: boolean;
219220
}
220221

221222
export interface SnykTarget {

src/scripts/sync/sync-projects-per-target.ts

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {
1212
} from '../../lib/types';
1313
import { ProjectUpdateType } from '../../lib/types';
1414
import { SupportedIntegrationTypesUpdateProject } from '../../lib/types';
15-
import { deactivateProject, listIntegrations, listProjects } from '../../lib';
15+
import { deactivateProject, listProjects } from '../../lib';
1616
import pMap = require('p-map');
1717
import { cloneAndAnalyze } from './clone-and-analyze';
1818
import { importSingleTarget } from './import-target';
@@ -67,6 +67,7 @@ export async function syncProjectsForTarget(
6767
try {
6868
targetMeta = await getMetaDataGenerator(origin)(targetData, host);
6969
} catch (e) {
70+
//TODO: if repo is deleted, deactivate all projects
7071
debug(e);
7172
const error = `Getting default branch via ${origin} API failed with error: ${e.message}`;
7273
projects.map((project) => {
@@ -85,35 +86,39 @@ export async function syncProjectsForTarget(
8586
const deactivate = [];
8687
const createProjects = [];
8788

88-
try {
89-
const res = await cloneAndAnalyze(origin, targetMeta!, projects, {
90-
exclusionGlobs: config.exclusionGlobs,
91-
entitlements: config.entitlements,
92-
manifestTypes: config.manifestTypes,
93-
});
94-
debug(
95-
'Analysis finished',
96-
JSON.stringify({
97-
deactivate: res.deactivate.length,
98-
import: res.import.length,
99-
}),
100-
);
101-
deactivate.push(...res.deactivate);
102-
createProjects.push(...res.import);
103-
} catch (e) {
104-
debug(e);
105-
const error = `Cloning and analysing the repo to deactivate projects failed with error: ${e.message}`;
106-
projects.map((project) => {
107-
failed.add({
108-
errorMessage: error,
109-
projectPublicId: project.id,
110-
from: 'active',
111-
to: 'deactivated',
112-
type: ProjectUpdateType.DEACTIVATE,
113-
dryRun: config.dryRun,
114-
target,
89+
if (targetMeta!.archived) {
90+
deactivate.push(...projects);
91+
} else {
92+
try {
93+
const res = await cloneAndAnalyze(origin, targetMeta!, projects, {
94+
exclusionGlobs: config.exclusionGlobs,
95+
entitlements: config.entitlements,
96+
manifestTypes: config.manifestTypes,
11597
});
116-
});
98+
debug(
99+
'Analysis finished',
100+
JSON.stringify({
101+
deactivate: res.deactivate.length,
102+
import: res.import.length,
103+
}),
104+
);
105+
deactivate.push(...res.deactivate);
106+
createProjects.push(...res.import);
107+
} catch (e) {
108+
debug(e);
109+
const error = `Cloning and analysing the repo to deactivate projects failed with error: ${e.message}`;
110+
projects.map((project) => {
111+
failed.add({
112+
errorMessage: error,
113+
projectPublicId: project.id,
114+
from: 'active',
115+
to: 'deactivated',
116+
type: ProjectUpdateType.DEACTIVATE,
117+
dryRun: config.dryRun,
118+
target,
119+
});
120+
});
121+
}
117122
}
118123

119124
// remove any projects that are to be deactivated from other actions

test/lib/git-clone.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ describe('gitClone', () => {
2727
SupportedIntegrationTypesUpdateProject.GITHUB,
2828
{
2929
branch: 'master',
30+
archived: false,
3031
cloneUrl: 'https://github.com/snyk-fixtures/monorepo-simple.git',
3132
sshUrl: 'git@github.com:snyk-fixtures/monorepo-simple.git',
3233
},
@@ -48,6 +49,7 @@ describe('gitClone', () => {
4849
SupportedIntegrationTypesUpdateProject.GITHUB,
4950
{
5051
branch: 'non-existent',
52+
archived: false,
5153
cloneUrl: 'https://github.com/snyk-fixtures/monorepo-simple.git',
5254
sshUrl: 'git@github.com:snyk-fixtures/monorepo-simple.git',
5355
},
@@ -87,6 +89,7 @@ describe('gitClone', () => {
8789
process.env.SNYK_LOG_PATH = __dirname;
8890
const res = await gitClone(SupportedIntegrationTypesUpdateProject.GHE, {
8991
branch: 'master',
92+
archived: false,
9093
cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
9194
sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
9295
});
@@ -104,6 +107,7 @@ describe('gitClone', () => {
104107

105108
const res = await gitClone(SupportedIntegrationTypesUpdateProject.GHE, {
106109
branch: 'non-existent',
110+
archived: false,
107111
cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
108112
sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
109113
});
@@ -122,6 +126,7 @@ describe('gitClone', () => {
122126

123127
const res = await gitClone(SupportedIntegrationTypesUpdateProject.GHE, {
124128
branch: 'non-existent',
129+
archived: false,
125130
cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
126131
sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
127132
});

test/lib/source-handlers/github/github.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ describe('buildGitCloneUrl', () => {
9595
process.env.GITHUB_TOKEN = 'secret_token';
9696
const url = github.buildGitCloneUrl({
9797
branch: 'main',
98+
archived: false,
9899
sshUrl: 'https://git@github.com:snyk-tech-services/snyk-api-import.git',
99100
cloneUrl: 'https://github.com/snyk-tech-services/snyk-api-import.git',
100101
});

test/scripts/sync/clone-and-analyze.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ describe('cloneAndAnalyze', () => {
6868

6969
const repoMeta: RepoMetaData = {
7070
branch: 'master',
71+
archived: false,
7172
cloneUrl: 'https://github.com/snyk-fixtures/monorepo-simple.git',
7273
sshUrl: 'git@github.com:snyk-fixtures/monorepo-simple.git',
7374
};
@@ -130,6 +131,7 @@ describe('cloneAndAnalyze', () => {
130131

131132
const repoMeta: RepoMetaData = {
132133
branch: 'master',
134+
archived: false,
133135
cloneUrl: 'https://github.com/snyk-fixtures/monorepo-simple.git',
134136
sshUrl: 'git@github.com:snyk-fixtures/monorepo-simple.git',
135137
};
@@ -204,6 +206,7 @@ describe('cloneAndAnalyze', () => {
204206

205207
const repoMeta: RepoMetaData = {
206208
branch: 'master',
209+
archived: false,
207210
cloneUrl: 'https://github.com/snyk-fixtures/monorepo-simple.git',
208211
sshUrl: 'git@github.com:snyk-fixtures/monorepo-simple.git',
209212
};
@@ -296,6 +299,7 @@ describe('cloneAndAnalyze', () => {
296299

297300
const repoMeta: RepoMetaData = {
298301
branch: 'master',
302+
archived: false,
299303
cloneUrl: 'https://github.com/snyk-fixtures/monorepo-simple.git',
300304
sshUrl: 'git@github.com:snyk-fixtures/monorepo-simple.git',
301305
};
@@ -321,6 +325,7 @@ describe('cloneAndAnalyze', () => {
321325

322326
const repoMeta: RepoMetaData = {
323327
branch: 'main',
328+
archived: false,
324329
cloneUrl: 'https://github.com/snyk-fixtures/no-supported-manifests.git',
325330
sshUrl: 'git@github.com:snyk-fixtures/no-supported-manifests.git',
326331
};
@@ -346,6 +351,7 @@ describe('cloneAndAnalyze', () => {
346351

347352
const repoMeta: RepoMetaData = {
348353
branch: 'master',
354+
archived: false,
349355
cloneUrl: 'https://github.com/snyk-fixtures/empty-repo.git',
350356
sshUrl: 'git@github.com:snyk-fixtures/empty-repo.git',
351357
};
@@ -371,6 +377,7 @@ describe('cloneAndAnalyze', () => {
371377

372378
const repoMeta: RepoMetaData = {
373379
branch: 'master',
380+
archived: false,
374381
cloneUrl:
375382
'https://github.com/snyk-fixtures/python-requirements-custom-name-inside-folder.git',
376383
sshUrl:
@@ -408,6 +415,7 @@ describe('cloneAndAnalyze', () => {
408415

409416
const repoMeta: RepoMetaData = {
410417
branch: 'master',
418+
archived: false,
411419
cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
412420
sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`,
413421
};
@@ -444,6 +452,7 @@ describe('cloneAndAnalyze', () => {
444452

445453
const repoMeta: RepoMetaData = {
446454
branch: 'master',
455+
archived: false,
447456
cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/docker-goof.git`,
448457
sshUrl: `git@${GHE_URL.host}/snyk-fixtures/docker-goof.git`,
449458
};
@@ -473,6 +482,7 @@ describe('cloneAndAnalyze', () => {
473482

474483
const repoMeta: RepoMetaData = {
475484
branch: 'master',
485+
archived: false,
476486
cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/docker-goof.git`,
477487
sshUrl: `git@${GHE_URL.host}/snyk-fixtures/docker-goof.git`,
478488
};

0 commit comments

Comments
 (0)