Skip to content

Commit

Permalink
Add support for accept_ms_testers_without_closed_task (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippeauriach committed Feb 2, 2023
1 parent 46d294f commit e1be7a8
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 1 deletion.
36 changes: 35 additions & 1 deletion action.js
Expand Up @@ -7,6 +7,7 @@ const {
moveTaskToProjectSection,
getProjectSections,
} = require("./lib/actions/asana");
const { getMobsuccessYMLFromRepo } = require("./lib/mobsuccessyml");

const customFieldLive = require("./lib/asana/custom-fields/live");
const customFieldStorybook = require("./lib/asana/custom-fields/storybook");
Expand Down Expand Up @@ -118,12 +119,14 @@ exports.findAsanaTaskId = function findAsanaTaskId({
};

exports.getActionParameters = function getActionParameters() {
const repository = github.context.payload.repository;
const pullRequest = github.context.payload.pull_request;
const action = core.getInput("action", { required: true });
const triggerPhrase = core.getInput("trigger-phrase") || "";
const amplifyUri = core.getInput("amplify-uri") || "";
const storybookAmplifyUri = core.getInput("storybook-amplify-uri") || "";
return {
repository,
pullRequest,
action,
triggerPhrase,
Expand Down Expand Up @@ -311,8 +314,31 @@ async function moveTaskToSprintAndEpicSection({ taskId, sectionId }) {
}
}

async function checkIfCanMergeWithoutAsanaTask({ repository, pullRequest }) {
const { assignees } = pullRequest;
const assigneeLogins = assignees.map(({ login }) => login);
if (!assigneeLogins.some((login) => login === "ms-testers")) {
return false;
}

// if mobsuccess.yml has the `accept_ms_testers_without_closed_task` flag set to true, we can merge
const mobsuccessyml = await getMobsuccessYMLFromRepo({
owner: repository.owner.login,
repo: repository.name,
});
const asanaSettings = mobsuccessyml.asana || {};
if (asanaSettings.accept_ms_testers_without_closed_task) {
console.log(
"accept_ms_testers_without_closed_task is set to true, ok to merge"
);
return true;
}
return false;
}

exports.action = async function action() {
const {
repository,
pullRequest,
action,
triggerPhrase,
Expand Down Expand Up @@ -391,7 +417,15 @@ exports.action = async function action() {
});
console.log("Task is completed?", completed);
if (!completed) {
throw new Error("Asana task is not yet completed, blocking merge");
// check if can merge without a completed asana task
const canMergeWithoutAsanaTask = await checkIfCanMergeWithoutAsanaTask(
{ repository, pullRequest }
);
if (!canMergeWithoutAsanaTask) {
throw new Error(
"Asana task is not yet completed, blocking merge"
);
}
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions action.test.js
Expand Up @@ -355,14 +355,61 @@ describe("Asana GitHub actions", () => {
const spyGetAsanaPRStatus = jest.spyOn(action, "getAsanaPRStatus");
action.getAsanaPRStatus.mockImplementation(() => "test-value");

let errorHasBeenThrown = false;
try {
await action.action();
} catch (error) {
errorHasBeenThrown = true;
expect(error).toBeInstanceOf(Error);
expect(error.message).toBe(
"Asana task is not yet completed, blocking merge"
);
}
expect(errorHasBeenThrown).toBe(true);
expect(spyGetAsanaPRStatus).toHaveBeenCalledTimes(1);
expect(spyGetAsanaPRStatus).toHaveBeenLastCalledWith({ pullRequest });
});

test("synchronize should not fail for not completed task with asana: accept_ms_testers_without_closed_task", async () => {
jest.resetAllMocks();
jest.resetModules();
jest.mock("./lib/actions/asana");
require("./lib/actions/asana").getTask.mockImplementation(() => ({
completed: false,
memberships: [],
}));
jest.mock("./lib/mobsuccessyml");
require("./lib/mobsuccessyml").getMobsuccessYMLFromRepo.mockImplementation(
() => ({
asana: { accept_ms_testers_without_closed_task: true },
})
);

const action = require("./action");
const pullRequest = {
number: 1234,
body:
"test-trigger-phrase https://app.asana.com/0/1200114135468212/1200114477821446/f",
requested_reviewers: [],
assignees: [{ login: "ms-testers" }],
};
jest.spyOn(action, "getActionParameters");
action.getActionParameters.mockImplementation(() => ({
repository: {
owner: {
login: "test-owner",
},
name: "test-repo",
},
pullRequest,
action: "synchronize",
triggerPhrase: "test-trigger-phrase",
}));

const spyGetAsanaPRStatus = jest.spyOn(action, "getAsanaPRStatus");
action.getAsanaPRStatus.mockImplementation(() => "test-value");

await action.action();

expect(spyGetAsanaPRStatus).toHaveBeenCalledTimes(1);
expect(spyGetAsanaPRStatus).toHaveBeenLastCalledWith({ pullRequest });
Expand Down
19 changes: 19 additions & 0 deletions lib/mobsuccessyml.js
@@ -0,0 +1,19 @@
const yaml = require("js-yaml");
const { octokit } = require("./actions/octokit");

exports.getMobsuccessYMLFromRepo = async function getMobsuccessYMLFromRepo({
owner,
repo,
}) {
try {
const { data } = await octokit.rest.repos.getContent({
owner,
repo,
path: ".mobsuccess.yml",
});
const content = Buffer.from(data.content, "base64").toString("utf8");
return yaml.load(content);
} catch (e) {
return {};
}
};

0 comments on commit e1be7a8

Please sign in to comment.