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

Get it working #2

Merged
merged 8 commits into from
Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from 5 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
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# Container Action Template
# First Interaction

To get started, click the `Use this template` button on this repository [which will create a new repository based on this template](https://github.blog/2019-06-06-generate-new-repositories-with-repository-templates/).
An action for filtering pull requests and issues from first-time contributors
damccorm marked this conversation as resolved.
Show resolved Hide resolved

# Usage

See [action.yml](action.yml)

```yaml
steps:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: 'Message that will be displayed on users' first issue'
damccorm marked this conversation as resolved.
Show resolved Hide resolved
pr-message: 'Message that will be displayed on users' first pr'
```

# License

The scripts and documentation in this project are released under the [MIT License](LICENSE)
4 changes: 0 additions & 4 deletions __tests__/main.test.ts

This file was deleted.

14 changes: 9 additions & 5 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
name: 'Container Action Template'
name: 'First interaction'
description: 'Get started with Container actions'
author: 'GitHub'
inputs:
myInput:
description: 'Input to use'
default: 'world'
inputs:
repo-token:

Choose a reason for hiding this comment

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

Nit: Are we going with a pattern of abbreviating names? repo-token vs. repository-token. Personal preference is longer version.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

repo-token is currently the standard across the board. I'm not inclined to change it at this point since it affects other actions as well (plus I just prefer repo haha)

description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
required: true
issue-message:
description: 'Comment to post on an individuals first issue'
pr-message:
description: 'Comment to post on an individuals first pull request'
runs:
using: 'docker'
image: 'Dockerfile'
11 changes: 0 additions & 11 deletions jest.config.js

This file was deleted.

106 changes: 102 additions & 4 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,116 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
const core = require('@actions/core');
const github = require('@actions/github');
const fs = require('fs');
function run() {
return __awaiter(this, void 0, void 0, function* () {
try {
const myInput = core.getInput('myInput');
core.debug(`Hello ${myInput} from inside a container`);
// Get github context data
// Get client and context
const client = new github.GitHub(core.getInput('repo-token', { required: true }));
const context = github.context;
console.log(`We can even get context data, like the repo: ${context.repo.repo}`);
if (context.payload.action !== 'opened') {
console.log('Nothing was opened');
return;
}
// Do nothing if its not a pr or issue
const isIssue = !!context.payload.issue;
if (!isIssue && !context.payload.pull_request) {
console.log('Not a pull request or issue');
return;
}
// Do nothing if its not their first contribution
console.log('Checking if its the users first contribution');
const sender = context.payload.sender.login;
const issue = context.issue;
const firstContribution = isIssue
? yield isFirstIssue(client, issue.owner, issue.repo, sender, issue.number)
: yield isFirstPull(client, issue.owner, issue.repo, sender, issue.number);
if (!firstContribution) {
console.log('Not the users first contribution');
return;
}
// Do nothing if no message set for this type of contribution
const message = isIssue
? core.getInput('issue-message')
: core.getInput('pr-message');
if (!message) {
console.log('No message provided for this type of contribution');
return;
}
// Add a comment to the appropriate place
console.log(`Adding message: ${message}`);
if (isIssue) {
yield client.issues.createComment({
owner: issue.owner,
repo: issue.repo,
issue_number: issue.number,
body: message
});
}
else {
yield client.pulls.createReview({
owner: issue.owner,
repo: issue.repo,
pull_number: issue.number,
body: message,
event: 'COMMENT'
});
}
}
catch (error) {
core.setFailed(error.message);
return;
}
});
}
function isFirstIssue(client, owner, repo, sender, number) {
return __awaiter(this, void 0, void 0, function* () {
const { status, data: issues } = yield client.issues.listForRepo({
owner: owner,
repo: repo,
creator: sender,
state: 'all'
});
if (status !== 200) {
throw new Error(`Received API status code ${status}`);
}
if (issues.length === 0) {
return true;
}
for (const issue of issues) {
const issueNumber = issue.number;
if (issueNumber < number && !issue.pull_request) {
return false;
}
}
return true;
});
}
// No way to filter pulls by creator
function isFirstPull(client, owner, repo, sender, number, page = 1) {
return __awaiter(this, void 0, void 0, function* () {
console.log('Checking...');
const { status, data: pulls } = yield client.pulls.list({
owner: owner,
repo: repo,
per_page: 100,
page: page,
state: 'all'
});
if (status !== 200) {
throw new Error(`Received API status code ${status}`);
}
if (pulls.length === 0) {
return true;
}
for (const pull of pulls) {
const login = pull.user.login;
const pullNumber = pull.number;
if (login === sender && pullNumber < number) {
return false;
}
}
return yield isFirstPull(client, owner, repo, sender, number, page + 1);
});
}
run();
144 changes: 139 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,151 @@
const core = require('@actions/core');
const github = require('@actions/github');
const fs = require('fs');

async function run() {
try {
const myInput = core.getInput('myInput');
core.debug(`Hello ${myInput} from inside a container`);

// Get github context data
// Get client and context
const client = new github.GitHub(
core.getInput('repo-token', {required: true})
);
const context = github.context;
console.log(`We can even get context data, like the repo: ${context.repo.repo}`)

if (context.payload.action !== 'opened') {
console.log('Nothing was opened');
damccorm marked this conversation as resolved.
Show resolved Hide resolved
return;
}

// Do nothing if its not a pr or issue
const isIssue = !!context.payload.issue;
damccorm marked this conversation as resolved.
Show resolved Hide resolved
if (!isIssue && !context.payload.pull_request) {
console.log('Not a pull request or issue');
damccorm marked this conversation as resolved.
Show resolved Hide resolved
return;
}

// Do nothing if its not their first contribution
console.log('Checking if its the users first contribution');
const sender = context.payload.sender.login;
damccorm marked this conversation as resolved.
Show resolved Hide resolved
const issue = context.issue;
const firstContribution = isIssue
? await isFirstIssue(
damccorm marked this conversation as resolved.
Show resolved Hide resolved
client,
issue.owner,
issue.repo,
sender,
issue.number
)
: await isFirstPull(
client,
issue.owner,
issue.repo,
sender,
issue.number
);
if (!firstContribution) {
console.log('Not the users first contribution');
return;
}

// Do nothing if no message set for this type of contribution
const message = isIssue
? core.getInput('issue-message')
: core.getInput('pr-message');
if (!message) {
damccorm marked this conversation as resolved.
Show resolved Hide resolved
console.log('No message provided for this type of contribution');
return;
}

// Add a comment to the appropriate place
console.log(`Adding message: ${message}`);
damccorm marked this conversation as resolved.
Show resolved Hide resolved
if (isIssue) {
await client.issues.createComment({
owner: issue.owner,
repo: issue.repo,
issue_number: issue.number,
body: message
});
} else {
await client.pulls.createReview({
owner: issue.owner,
repo: issue.repo,
pull_number: issue.number,
body: message,
event: 'COMMENT'
});
}
} catch (error) {
core.setFailed(error.message);
return;
}
}

async function isFirstIssue(
damccorm marked this conversation as resolved.
Show resolved Hide resolved
client,
owner,
repo,
sender,
number
): Promise<boolean> {
const {status, data: issues} = await client.issues.listForRepo({
owner: owner,
repo: repo,
creator: sender,
state: 'all'
});

if (status !== 200) {
throw new Error(`Received API status code ${status}`);
damccorm marked this conversation as resolved.
Show resolved Hide resolved
}

if (issues.length === 0) {
return true;
}

for (const issue of issues) {
const issueNumber = issue.number;
damccorm marked this conversation as resolved.
Show resolved Hide resolved
if (issueNumber < number && !issue.pull_request) {
return false;
}
}

return true;
}

// No way to filter pulls by creator
async function isFirstPull(
damccorm marked this conversation as resolved.
Show resolved Hide resolved
damccorm marked this conversation as resolved.
Show resolved Hide resolved
client,
owner,
repo,
sender,
number,
page = 1
): Promise<boolean> {
console.log('Checking...');
damccorm marked this conversation as resolved.
Show resolved Hide resolved
const {status, data: pulls} = await client.pulls.list({
owner: owner,
repo: repo,
per_page: 100,
page: page,
state: 'all'
});

if (status !== 200) {
throw new Error(`Received API status code ${status}`);
damccorm marked this conversation as resolved.
Show resolved Hide resolved
}

if (pulls.length === 0) {
return true;
}

for (const pull of pulls) {
const login = pull.user.login;
const pullNumber = pull.number;
if (login === sender && pullNumber < number) {
return false;
}
}

return await isFirstPull(client, owner, repo, sender, number, page + 1);
}

run();
Binary file modified toolkit/actions-github-0.0.0.tgz
Binary file not shown.