Skip to content

Migrating to Github Actions

James James edited this page Jun 29, 2021 · 1 revision

Migrating To Github Actions

Introduction

In order to migrate a feature to GitHub actions, the following must first be understood.

  1. Currently, oppiabot is based on probot, which was developed before GitHub actions got released.
  2. Probot and Github actions uses the same clients (octokit/rest, octokit/graphql) to access the Github API.
  3. From Probot, we access the Github API client via context.github.
  4. From Github Actions, we access the Github API client via octokit, where octokit = new Github(token).
  5. From Probot and Github actions, payload details can be accessed via context.payload.

Migrating A Feature

To migrate a feature from probot to GitHub actions, the following need to be done.

1. Updating the Event name:

With the current GitHub actions setup, we are following the following convention for event names EventType_target_ActionType. For example, to listen when a pull request gets reviewed, we would change the event name in ./constants.js to pull_request_target_review_submitted.

2. Add an entry to the dispatcher:

Similar to what was done in probot, to ensure the action gets routed to the appropriate handler, we need to add it to the GitHub actions dispatcher which is located at ./actions/src/dispatcher.js

3. Add necessary imports:

In the file which is being migrated, add the following imports.

const core = require('@actions/core');
const { context, GitHub } = require('@actions/github');

4. Create the GitHub API client:

In each function which requires access to the github api, use the following to create octokit

const token = core.getInput('repo-token');
const octokit = new GitHub(token);

5. Replacing Probot with Actions:

Replace context.github with octokit to use the Github Action client.

Replace all context.repo(), context.issue() usages with the actual object required. In Github Actions, context.repo is not a function, but instead an object containing details about the repo. So for places where you'd use context.repo({issue_number: 20}), replace it with {issue_number:20, ...context.repo}. This can also be done with context.issue.

Remove context from the arguments of the function. This is because it is not required, and context is gotten directly from the file as described in step 3.

6. Remove Entry from Index.js:

After doing the above, you have successfully migrated the feature to Github actions. It can now be removed from index.js to prevent it from being called by probot.

Migrating Tests

To migrate tests, you need to do the following.

1. Add imports:

Add the following import statements in addition to the required imports:

const github = require('@actions/github');
const core = require('@actions/core');
const dispatcher = require('../actions/src/dispatcher');

2. Mocking:

We need to mock the github api client similar to what was done for probot.

let octokit = {
  issues: {
    createComment: jasmine.createSpy('createComment').and.resolveTo({}),
    addAssignees: jasmine.createSpy('addAssignees').and.resolveTo({}),
    // Add more functions to be spied on.
  },
};
// Mock GitHub API.
Object.setPrototypeOf(github.GitHub, function () {
  return octokit;
});
// Spy on token.
spyOn(core, 'getInput').and.returnValue('sample-token');

You can also add different more spies depending on what functions are being used.

3. Dispatching Events:

Remove all mentions of robot.receive(...) with dispatcher.dispatch(payload). It is important to note that the payload being passed to the dispatcher should only contain payload data. For example, if we are dispatching the issues.assigned.json payload, we would call dispatcher.dispatch(issuesAssignedPayload.payload) so as to get the actual payload.

Conclusion

Once all the above is done, the feature has been migrated successfully, and your PR is ready to be created. To see this in action, check out the work done on migrating the WIP/Draft PRs check to GitHub actions.