Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/test-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
continue-on-error: true
run: |
npm install
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
./node_modules/.bin/jest --json --outputFile=${{env.jest-output-file}} ./src/

- name: Process jest results
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
- name: Create GitHub Deployment
id: defaults
continue-on-error: true # Setting to true so the job doesn't fail if updating the board fails.
uses: im-open/[email protected].10 # You may also reference just the major or major.minor version
uses: im-open/[email protected].8 # You may also reference just the major or major.minor version
with:
workflow-actor: ${{ github.actor }} # This will add the user who kicked off the workflow to the deployment payload
token: ${{ secrets.GITHUB_TOKEN }} # If a different token is used, update github-login with the corresponding account
Expand Down
65 changes: 35 additions & 30 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42107,17 +42107,21 @@ var require_deployments = __commonJS({
var { Octokit } = require_dist_node12();
var { graphql } = require_dist_node6();
var WORKFLOW_DEPLOY = 'workflowdeploy';
var ALLOWED_STATUSES = [
'success',
'error',
'failure',
'inactive',
'in_progress',
'queued',
'pending'
];
var ALLOWED_STATUSES = {
SUCCESS: 'success',
ERROR: 'error',
FAILURE: 'failure',
INACTIVE: 'inactive',
IN_PROGRESS: 'in_progress',
QUEUED: 'queued',
PENDING: 'pending'
};
var createOctokitClient = token => new Octokit({ auth: token });
var createOctokitGraphQLClient = token =>
graphql.defaults({ headers: { authorization: `token ${token}` } });
async function inactivatePriorDeployments(context, currentDeploymentNodeId) {
const octokit = new Octokit({ auth: context.token });
const octokit = createOctokitClient(context.token);
const octokitGraphQl = createOctokitGraphQLClient(context.token);
const params = {
owner: context.owner,
repo: context.repo,
Expand All @@ -42126,19 +42130,14 @@ var require_deployments = __commonJS({
per_page: 100
};
const deploymentsList = (
await octokit.paginate(octokit.rest.repos.listDeployments, params)
).filter(
d =>
d.node_id != currentDeploymentNodeId &&
d.payload.entity == context.entity &&
d.payload.instance == context.instance
);
await getPriorDeployments(octokit, context.entity, context.instance, params)
).filter(d => d.node_id != currentDeploymentNodeId);
const statuses = await getPriorDeploymentStatuses(
context.token,
octokitGraphQl,
deploymentsList.map(d => d.node_id)
);
for (let i = 0; i < statuses.deployments.length; i++) {
let deploymentQl = statuses.deployments[i];
for (let i = 0; i < statuses.length; i++) {
let deploymentQl = statuses[i];
let deployment = deploymentsList.filter(d => d.node_id == deploymentQl.id)[0];
for (let j = 0; j < deploymentQl.statuses.nodes.length; j++) {
const status = deploymentQl.statuses.nodes[j];
Expand All @@ -42156,12 +42155,12 @@ var require_deployments = __commonJS({
}
}
}
async function getPriorDeploymentStatuses(token, deploymentNodeIds) {
const octokitGraphQl = graphql.defaults({
headers: {
authorization: `token ${token}`
}
});
async function getPriorDeployments(octokit, entity, instance, params) {
return (await octokit.paginate(octokit.rest.repos.listDeployments, params)).filter(
d => d.payload.entity == entity && d.payload.instance == instance
);
}
async function getPriorDeploymentStatuses(octokitGraphQl, deploymentNodeIds) {
const statuses = [];
const statusesQuery = `
query($deploymentNodeIds: [ID!]!) {
Expand Down Expand Up @@ -42194,7 +42193,7 @@ var require_deployments = __commonJS({
return statuses;
}
async function createDeployment2(context) {
const octokit = new Octokit({ auth: context.token });
const octokit = createOctokitClient(context.token);
const deployment = (
await octokit.rest.repos.createDeployment({
owner: context.owner,
Expand Down Expand Up @@ -42252,7 +42251,12 @@ var require_deployments = __commonJS({
}
module2.exports = {
ALLOWED_STATUSES,
createDeployment: createDeployment2
WORKFLOW_DEPLOY,
createDeployment: createDeployment2,
createOctokitClient,
createOctokitGraphQLClient,
getPriorDeployments,
getPriorDeploymentStatuses
};
}
});
Expand Down Expand Up @@ -42317,7 +42321,7 @@ var require_library = __commonJS({
const workflow_run_id = github.context.runId;
const owner = github.context.repo.owner;
const repo = github.context.repo.repo;
if (!ALLOWED_STATUSES.map(s => s.toLowerCase()).includes(deployment_status.toLowerCase())) {
if (!Object.values(ALLOWED_STATUSES).includes(deployment_status.toLowerCase())) {
throw { name: INVALID_STATUS, message: `Invalid deployment status: ${deployment_status}` };
}
return new context(
Expand All @@ -42337,7 +42341,8 @@ var require_library = __commonJS({
}
module2.exports = {
INVALID_STATUS,
setup: setup2
setup: setup2,
context
};
}
});
Expand Down
63 changes: 35 additions & 28 deletions src/deployments.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
const { Octokit } = require('@octokit/rest');
const { graphql } = require('@octokit/graphql');
const WORKFLOW_DEPLOY = 'workflowdeploy';
const ALLOWED_STATUSES = [
'success',
'error',
'failure',
'inactive',
'in_progress',
'queued',
'pending'
];
const ALLOWED_STATUSES = {
SUCCESS: 'success',
ERROR: 'error',
FAILURE: 'failure',
INACTIVE: 'inactive',
IN_PROGRESS: 'in_progress',
QUEUED: 'queued',
PENDING: 'pending'
};

const createOctokitClient = token => new Octokit({ auth: token });
const createOctokitGraphQLClient = token =>
graphql.defaults({ headers: { authorization: `token ${token}` } });
Comment on lines +14 to +16

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an advantage to defining a function that creates an octokit client as opposed to creating a single client that is passed to the functions that need it? It seems like having a single client that all the different functions use might be better than each function creating its own version of the client.

Copy link
Contributor Author

@hpractv hpractv Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is getting used by the deployment testing file, too. I wanted to make sure the setting params for these clients were the same in both the runtime code as well as the jest test.


async function inactivatePriorDeployments(context, currentDeploymentNodeId) {
const octokit = new Octokit({ auth: context.token });
const octokit = createOctokitClient(context.token);
const octokitGraphQl = createOctokitGraphQLClient(context.token);

const params = {
owner: context.owner,
Expand All @@ -23,21 +28,16 @@ async function inactivatePriorDeployments(context, currentDeploymentNodeId) {
};

const deploymentsList = (
await octokit.paginate(octokit.rest.repos.listDeployments, params)
).filter(
d =>
d.node_id != currentDeploymentNodeId &&
d.payload.entity == context.entity &&
d.payload.instance == context.instance
);
await getPriorDeployments(octokit, context.entity, context.instance, params)
).filter(d => d.node_id != currentDeploymentNodeId);

const statuses = await getPriorDeploymentStatuses(
context.token,
octokitGraphQl,
deploymentsList.map(d => d.node_id)
);

for (let i = 0; i < statuses.deployments.length; i++) {
let deploymentQl = statuses.deployments[i];
for (let i = 0; i < statuses.length; i++) {
let deploymentQl = statuses[i];
let deployment = deploymentsList.filter(d => d.node_id == deploymentQl.id)[0];

for (let j = 0; j < deploymentQl.statuses.nodes.length; j++) {
Expand All @@ -58,13 +58,13 @@ async function inactivatePriorDeployments(context, currentDeploymentNodeId) {
}
}

async function getPriorDeploymentStatuses(token, deploymentNodeIds) {
const octokitGraphQl = graphql.defaults({
headers: {
authorization: `token ${token}`
}
});
async function getPriorDeployments(octokit, entity, instance, params) {
return (await octokit.paginate(octokit.rest.repos.listDeployments, params)).filter(
d => d.payload.entity == entity && d.payload.instance == instance
);
}

async function getPriorDeploymentStatuses(octokitGraphQl, deploymentNodeIds) {
const statuses = [];
const statusesQuery = `
query($deploymentNodeIds: [ID!]!) {
Expand Down Expand Up @@ -101,7 +101,8 @@ async function getPriorDeploymentStatuses(token, deploymentNodeIds) {
}

async function createDeployment(context) {
const octokit = new Octokit({ auth: context.token });
const octokit = createOctokitClient(context.token);

// create deployment record
const deployment = (
await octokit.rest.repos.createDeployment({
Expand All @@ -126,6 +127,7 @@ async function createDeployment(context) {
const inactivate = new Promise((resolve, reject) =>
resolve(inactivatePriorDeployments(context, deployment.node_id))
);

inactivate.then(async () => {
await createDeploymentStatus(
octokit,
Expand Down Expand Up @@ -164,5 +166,10 @@ async function createDeploymentStatus(

module.exports = {
ALLOWED_STATUSES,
createDeployment
WORKFLOW_DEPLOY,
createDeployment,
createOctokitClient,
createOctokitGraphQLClient,
getPriorDeployments,
getPriorDeploymentStatuses
};
99 changes: 99 additions & 0 deletions src/deployments.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const { describe, test, expect, beforeEach, beforeAll, afterAll } = require('@jest/globals');
const {
ALLOWED_STATUSES,
WORKFLOW_DEPLOY,
createOctokitClient,
createOctokitGraphQLClient,
getPriorDeployments,
getPriorDeploymentStatuses,
createDeployment
} = require('./deployments.js');
const { context } = require('./library.js');

const token = process.env['GITHUB_TOKEN'];
let octokit;
let octokitGraphQl;
const owner = 'im-open';
const repo = 'create-github-deployment';
const create_environment = 'INTEGRATION';
const pull_environment = 'DEV';
const entity = 'create-github-deployment';
const instance = 'action';
const priorDeployments = [];
const priorDeploymentStatuses = [];
let testDeploymentId = null;
const workflow_actor = 'test-actor';

// Create the octokit clients
beforeAll(() => {
octokit = createOctokitClient(token);
octokitGraphQl = createOctokitGraphQLClient(token);
});

//clean up test deployment
afterAll(async () => {
if (testDeploymentId !== null) {
setTimeout(async () => {
await octokit.rest.repos.deleteDeployment({
owner: owner,
repo: repo,
deployment_id: testDeploymentId
});
octokit = null;
octokitGraphQl = null;
}, 5000);
}
});

describe('deployments', () => {
let firstDeploymentId;

test('get the deployments', async () => {
const deployments = await getPriorDeployments(octokit, entity, instance, {
owner: owner,
repo: repo,
task: WORKFLOW_DEPLOY,
environment: pull_environment,
per_page: 100
});
expect(deployments).toBeDefined();
expect(deployments.length).toBeGreaterThan(0);
expect(deployments[0].payload).toBeDefined();
firstDeploymentId = deployments[0].node_id;

priorDeployments.push(...deployments);
});

test('get the deployment statuses', async () => {
const statuses = await getPriorDeploymentStatuses(octokitGraphQl, [firstDeploymentId]);
expect(statuses).toBeDefined();
expect(statuses.length).toBeGreaterThan(0);

expect(statuses[0].statuses).toBeDefined();
expect(statuses[0].statuses.nodes).toBeDefined();
expect(statuses[0].statuses.nodes.length).toBeGreaterThan(0);

priorDeploymentStatuses.push(...statuses);
});

test('create deployment', async () => {
testDeploymentId = await createDeployment(
new context(
workflow_actor,
token,
create_environment,
'v1',
ALLOWED_STATUSES.SUCCESS,
'Testing deployment creation',
entity,
instance,
'https://github.com',
'https://github.com',
owner,
repo
)
);

expect(Number.isNaN(testDeploymentId)).toBe(false);
});
});
5 changes: 3 additions & 2 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function setup() {
const owner = github.context.repo.owner;
const repo = github.context.repo.repo;

if (!ALLOWED_STATUSES.map(s => s.toLowerCase()).includes(deployment_status.toLowerCase())) {
if (!Object.values(ALLOWED_STATUSES).includes(deployment_status.toLowerCase())) {
throw { name: INVALID_STATUS, message: `Invalid deployment status: ${deployment_status}` };
}

Expand All @@ -79,5 +79,6 @@ function setup() {

module.exports = {
INVALID_STATUS,
setup
setup,
context
};
Loading
Loading