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

feat: history-limit input #49

Merged
merged 2 commits into from
Dec 18, 2024
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
79 changes: 62 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ your repository.

### Modify the Pull Request Template

By default, this action will append the visualization to the bottom of the PR description.
By default, the action will append the visualization to the bottom of the PR description.
If you are using a [pull request template](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository),
you can specify the location of the visualization in the template by adding a [HTML comment](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#hiding-content-with-comments)
that contains `branch-stack` inside of it:
Expand All @@ -76,7 +76,7 @@ that contains `branch-stack` inside of it:
[ ] Baz
```

This action will look for this comment and insert the visualization underneath the comment
The action will look for this comment and insert the visualization underneath the comment
when it runs. It will also leave behind the comment, so that the next time it runs, it will
be able to use it again to update the visualization:

Expand All @@ -98,17 +98,17 @@ be able to use it again to update the visualization:

> [!WARNING]
> Be careful not to add content between the comment and the
> visualization, as this action will replace that content each time it
> visualization, as the action will replace that content each time it
> updates your PR. Adding content above the tag, or below the list is
> safe though!

### Manual Configuration
## Manual Configuration

If you are using Git Town v11 and below, or are setting up this action for a repository
that doesn't have a `.git-branches.toml`, you will need to tell this action what the
If you are using Git Town v11 and below, or are setting up the action for a repository
that doesn't have a `.git-branches.toml`, you will need to tell the action what the
main branch and perennial branches are for your repository.

#### Main Branch
### Main Branch

The main branch is the default parent branch for new feature branches, and can be
specified using the `main-branch` input:
Expand All @@ -119,10 +119,10 @@ specified using the `main-branch` input:
main-branch: 'main'
```

This action will default to your repository's default branch, which it fetches via
The action will default to your repository's default branch, which it fetches via
the GitHub REST API.

#### Perennial Branches
### Perennial Branches

Perennial branches are long lived branches and are never shipped.

Expand All @@ -139,25 +139,70 @@ be done with the `perennial-branches` and `perennial-regex` inputs respectively:
perennial-regex: '^release-.*$'
```

Both inputs can be used at the same time. This action will merge the perennial
Both inputs can be used at the same time. The action will merge the perennial
branches given into a single, de-duplicated list.

#### Skip Single Stacks
## Customization

If you don't want the stack description to appear on pull requests which are not part of a stack, you can add `skip-single-stacks: true` to the job.
### Skip Single Stacks

This skips all pull requests which point to a main or perennial branch and have no children pull requests pointing to it.
If you don't want the stack visualization to appear on pull requests which are **not** part
of a stack, add `skip-single-stacks: true` to the action's inputs.

A pull request is considered to be **not** a part of a stack if:
- It has no child pull requests.
- It's parent is the main branch or a perennial branch.

```yaml
- uses: git-town/action@v1
with:
perennial-branches: |
dev
staging
prod
skip-single-stacks: true
```

### History Limit

In order to accurately visualize stacked changes, the action needs to fetch _all_ open
and closed pull requests. This can problematic for larger/older repositories that have
a large number of closed pull requests.

The action can be configured to fetch a limited number of closed pull requests. This is
customizable with the `history-limit` input:

```yaml
- uses: git-town/action@v1
with:
history-limit: '500' # Only fetch the latest 500 closed pull requests
```

> [!NOTE]
> This only applies to closed pull requests. Open pull requests will be completely fetched
> regardless of the `history-limit`.

## Reference

```yaml
inputs:
github-token:
required: true
default: ${{ github.token }}
main-branch:
required: false
default: ''
perennial-branches:
required: false
default: ''
perennial-regex:
required: false
default: ''
skip-single-stacks:
required: false
default: false
history-limit:
required: false
default: '0'
```


## License

The scripts and documentation in this project are released under the [MIT License](LICENSE).
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ inputs:
skip-single-stacks:
required: false
default: false
history-limit:
required: false
default: '0'

runs:
using: 'node20'
Expand Down
73 changes: 54 additions & 19 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47076,12 +47076,26 @@ var inputs = {
return core2.getInput("github-token", { required: true, trimWhitespace: true });
},
getSkipSingleStacks() {
const input = core2.getBooleanInput("skip-single-stacks", {
required: false,
trimWhitespace: true
});
core2.startGroup("Inputs: Skip single stacks");
const input = core2.getBooleanInput("skip-single-stacks", { required: false });
core2.info(input.toString());
core2.endGroup();
return input;
},
getHistoryLimit() {
const input = core2.getInput("history-limit", {
required: false,
trimWhitespace: true
});
const historyLimit = Number.parseInt(input, 10);
core2.startGroup("Inputs: History limit");
core2.info(input);
core2.endGroup();
return historyLimit;
},
async getMainBranch(octokit, config2, context3) {
const {
data: { default_branch: defaultBranch }
Expand Down Expand Up @@ -47155,24 +47169,44 @@ var inputs = {
throw error;
}
},
async getPullRequests(octokit, context3) {
const pullRequests = await octokit.paginate(
"GET /repos/{owner}/{repo}/pulls",
{
...context3.repo,
state: "all",
per_page: 100
},
(response) => response.data.map(
(item) => ({
number: item.number,
base: { ref: item.base.ref },
head: { ref: item.head.ref },
body: item.body ?? void 0,
state: item.state
})
async getPullRequests(octokit, context3, historyLimit) {
function toPullRequest(item) {
return {
number: item.number,
base: { ref: item.base.ref },
head: { ref: item.head.ref },
body: item.body ?? void 0,
state: item.state
};
}
let closedPullRequestCount = 0;
const [openPullRequests, closedPullRequests] = await Promise.all([
octokit.paginate(
"GET /repos/{owner}/{repo}/pulls",
{
...context3.repo,
state: "open",
per_page: 100
},
(response) => response.data.map(toPullRequest)
),
octokit.paginate(
"GET /repos/{owner}/{repo}/pulls",
{
...context3.repo,
state: "closed",
per_page: 100
},
(response, done) => {
closedPullRequestCount += response.data.length;
if (historyLimit > 0 && closedPullRequestCount >= historyLimit) {
done();
}
return response.data.map(toPullRequest);
}
)
);
]);
const pullRequests = [...openPullRequests, ...closedPullRequests];
pullRequests.sort((a, b) => b.number - a.number);
core2.startGroup("Inputs: Pull requests");
core2.info(
Expand Down Expand Up @@ -47224,10 +47258,11 @@ async function run() {
return;
}
const octokit = github2.getOctokit(inputs.getToken());
const historyLimit = inputs.getHistoryLimit();
const [mainBranch, remoteBranches, pullRequests] = await Promise.all([
inputs.getMainBranch(octokit, config, github2.context),
inputs.getRemoteBranches(octokit, github2.context),
inputs.getPullRequests(octokit, github2.context)
inputs.getPullRequests(octokit, github2.context, historyLimit)
]);
const perennialBranches = await inputs.getPerennialBranches(config, remoteBranches);
const context3 = {
Expand Down
Loading
Loading