Skip to content

Commit

Permalink
feat: add unarchiving plugin (#692)
Browse files Browse the repository at this point in the history
* feat: add unarchiving plugin

* fix: fixed some broken test cases and added trailing newling

---------

Co-authored-by: Yadhav Jayaraman <[email protected]>
  • Loading branch information
randomcascade and decyjphr authored Jan 20, 2025
1 parent 3b7eb05 commit 774b2e5
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 30 deletions.
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 @@ -326,38 +327,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.');
});
});

0 comments on commit 774b2e5

Please sign in to comment.