Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add unarchiving plugin #692

Open
wants to merge 2 commits into
base: main-enterprise
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions lib/plugins/archive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const NopCommand = require('../nopcommand');

function returnValue(shouldContinue, nop) {
return { shouldContinue, nopCommands: nop };
}

module.exports = class Archive {
constructor(nop, github, repo, settings, log) {
this.github = github;
this.repo = repo;
this.settings = settings;
this.log = log;
this.nop = nop;
}

// Returns true if plugin application should continue, false otherwise
async sync() {
// Fetch repository details using REST API
const { data: repoDetails } = await this.github.repos.get({
owner: this.repo.owner,
repo: this.repo.repo
});
if (typeof this.settings?.archived !== 'undefined') {
this.log.debug(`Checking if ${this.repo.owner}/${this.repo.repo} is archived`);

this.log.debug(`Repo ${this.repo.owner}/${this.repo.repo} is ${repoDetails.archived ? 'archived' : 'not archived'}`);

if (repoDetails.archived) {
if (this.settings.archived) {
this.log.debug(`Repo ${this.repo.owner}/${this.repo.repo} already archived, inform other plugins should not run.`);
return returnValue(false);
}
else {
this.log.debug(`Unarchiving ${this.repo.owner}/${this.repo.repo}`);
if (this.nop) {
return returnValue(true, [new NopCommand(this.constructor.name, this.repo, this.github.repos.update.endpoint(this.settings), 'will unarchive')]);
}
else {
// Unarchive the repository using REST API
const updateResponse = await this.github.repos.update({
owner: this.repo.owner,
repo: this.repo.repo,
archived: false
});
this.log.debug(`Unarchive result ${JSON.stringify(updateResponse)}`);

return returnValue(true);
}
}
}
else {
if (this.settings.archived) {
this.log.debug(`Archiving ${this.repo.owner}/${this.repo.repo}`);
if (this.nop) {
return returnValue(false, [new NopCommand(this.constructor.name, this.repo, this.github.repos.update.endpoint(this.settings), 'will archive')]);
}
else {
// Archive the repository using REST API
const updateResponse = await this.github.repos.update({
owner: this.repo.owner,
repo: this.repo.repo,
archived: true
});
this.log.debug(`Archive result ${JSON.stringify(updateResponse)}`);

return returnValue(false);
}
}
else {
this.log.debug(`Repo ${this.repo.owner}/${this.repo.repo} is not archived, ignoring.`);
return returnValue(true);
}
}
}
else {
if (repoDetails.archived) {
this.log.debug(`Repo ${this.repo.owner}/${this.repo.repo} is archived, ignoring.`);
return returnValue(false);
}
else {
this.log.debug(`Repo ${this.repo.owner}/${this.repo.repo} is not archived, proceed as usual.`);
return returnValue(true);
}
}
}
};
65 changes: 35 additions & 30 deletions lib/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const errorTemplate = require('./error')
const Glob = require('./glob')
const NopCommand = require('./nopcommand')
const MergeDeep = require('./mergeDeep')
const Archive = require('./plugins/archive')
const env = require('./env')
const CONFIG_PATH = env.CONFIG_PATH
const eta = new Eta({ views: path.join(__dirname) })
Expand Down Expand Up @@ -318,38 +319,42 @@ ${this.results.reduce((x, y) => {
if (overrideRepoConfig) {
repoConfig = this.mergeDeep.mergeDeep({}, repoConfig, overrideRepoConfig)
}
if (repoConfig) {
try {
this.log.debug(`found a matching repoconfig for this repo ${JSON.stringify(repoConfig)}`)
const childPlugins = this.childPluginsList(repo)
const RepoPlugin = Settings.PLUGINS.repository
return new RepoPlugin(this.nop, this.github, repo, repoConfig, this.installation_id, this.log, this.errors).sync().then(res => {
this.appendToResults(res)
return Promise.all(
childPlugins.map(([Plugin, config]) => {
return new Plugin(this.nop, this.github, repo, config, this.log, this.errors).sync()
}))
}).then(res => {
this.appendToResults(res)
})
} catch (e) {
if (this.nop) {
const nopcommand = new NopCommand(this.constructor.name, this.repo, null, `${e}`, 'ERROR')
this.log.error(`NOPCOMMAND ${JSON.stringify(nopcommand)}`)
this.appendToResults([nopcommand])
// throw e
} else {
throw e
const {shouldContinue, nopCommands} = await new Archive(this.nop, this.github, repo, repoConfig, this.log).sync()
if (nopCommands) this.appendToResults(nopCommands)
if (shouldContinue) {
if (repoConfig) {
try {
this.log.debug(`found a matching repoconfig for this repo ${JSON.stringify(repoConfig)}`)
const childPlugins = this.childPluginsList(repo)
const RepoPlugin = Settings.PLUGINS.repository
return new RepoPlugin(this.nop, this.github, repo, repoConfig, this.installation_id, this.log, this.errors).sync().then(res => {
this.appendToResults(res)
return Promise.all(
childPlugins.map(([Plugin, config]) => {
return new Plugin(this.nop, this.github, repo, config, this.log, this.errors).sync()
}))
}).then(res => {
this.appendToResults(res)
})
} catch (e) {
if (this.nop) {
const nopcommand = new NopCommand(this.constructor.name, this.repo, null, `${e}`, 'ERROR')
this.log.error(`NOPCOMMAND ${JSON.stringify(nopcommand)}`)
this.appendToResults([nopcommand])
// throw e
} else {
throw e
}
}
} else {
this.log.debug(`Didnt find any a matching repoconfig for this repo ${JSON.stringify(repo)} in ${JSON.stringify(this.repoConfigs)}`)
const childPlugins = this.childPluginsList(repo)
return Promise.all(childPlugins.map(([Plugin, config]) => {
return new Plugin(this.nop, this.github, repo, config, this.log, this.errors).sync().then(res => {
this.appendToResults(res)
})
}))
}
} else {
this.log.debug(`Didnt find any a matching repoconfig for this repo ${JSON.stringify(repo)} in ${JSON.stringify(this.repoConfigs)}`)
const childPlugins = this.childPluginsList(repo)
return Promise.all(childPlugins.map(([Plugin, config]) => {
return new Plugin(this.nop, this.github, repo, config, this.log, this.errors).sync().then(res => {
this.appendToResults(res)
})
}))
}
}

Expand Down
68 changes: 68 additions & 0 deletions test/unit/lib/plugins/archive.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const Archive = require('../../../../lib/plugins/archive');
const NopCommand = require('../../../../lib/nopcommand');

describe('Archive Plugin', () => {
let github;
let log;
let repo;
let settings;
let nop;

beforeEach(() => {
github = {
repos: {
get: jest.fn(),
update: jest.fn()
}
};
log = {
debug: jest.fn(),
};
repo = { owner: 'test-owner', repo: 'test-repo' };
settings = {};
nop = false;
});

it('should return false if the repository is archived and settings.archived is true', async () => {
github.repos.get.mockResolvedValue({ data: { archived: true } });
settings.archived = true;

const archive = new Archive(nop, github, repo, settings, log);
const result = await archive.sync();

expect(result.shouldContinue).toBe(false);
});

it('should return true if the repository is archived and settings.archived is false', async () => {
github.repos.get.mockResolvedValue({ data: { archived: true } });
settings.archived = false;

const archive = new Archive(nop, github, repo, settings, log);
const result = await archive.sync();

expect(result.shouldContinue).toBe(true);
expect(log.debug).toHaveBeenCalledWith('Unarchiving test-owner/test-repo');
});

it('should return false if the repository is not archived and settings.archived is true', async () => {
github.repos.get.mockResolvedValue({ data: { archived: false } });
settings.archived = true;

const archive = new Archive(nop, github, repo, settings, log);
const result = await archive.sync();

expect(result.shouldContinue).toBe(false);
expect(log.debug).toHaveBeenCalledWith('Archiving test-owner/test-repo');
});

it('should return true if the repository is not archived and settings.archived is false', async () => {
github.repos.get.mockResolvedValue({ data: { archived: false } });
settings.archived = false;

const archive = new Archive(nop, github, repo, settings, log);
const result = await archive.sync();

expect(result.shouldContinue).toBe(true);
expect(log.debug).toHaveBeenCalledWith('Repo test-owner/test-repo is not archived, ignoring.');
});
});