+1
-1
@@ -99,4 +99,4 @@ __tests__/runner/*
|
|||||||
lib/**/*
|
lib/**/*
|
||||||
|
|
||||||
lib
|
lib
|
||||||
pr-collector/dist
|
src/pr-collector/dist
|
||||||
@@ -100,7 +100,8 @@ Below is a complete example showcasing how to define a build, which is executed
|
|||||||
- Build changelog, given the tag
|
- Build changelog, given the tag
|
||||||
- Create release on GitHub - specifying body with constructed changelog
|
- Create release on GitHub - specifying body with constructed changelog
|
||||||
|
|
||||||
> Note: Pre v4 PRs will only show up in the changelog if assigned one of the default label categories "feature", "fix" or "test". Starting with v4 these PRs will be in the `Uncategorized` section.
|
> [!NOTE]
|
||||||
|
> Pre v4 PRs will only show up in the changelog if assigned one of the default label categories "feature", "fix" or "test". Starting with v4 these PRs will be in the `Uncategorized` section.
|
||||||
|
|
||||||
<details><summary><b>Example</b></summary>
|
<details><summary><b>Example</b></summary>
|
||||||
<p>
|
<p>
|
||||||
@@ -169,15 +170,19 @@ jobs:
|
|||||||
|
|
||||||
### Note
|
### Note
|
||||||
|
|
||||||
> **Warning**: When running this action for non tags trigger the `toTag` will be automatically resolved using the latest tag as retrieved by the git API.
|
> [!IMPORTANT]
|
||||||
|
> When running this action for non tags trigger the `toTag` will be automatically resolved using the latest tag as retrieved by the git API.
|
||||||
|
|
||||||
> **Note**: The first release tag is a special case since there is no previous release the action can reference to. For this case, there are 2 options:
|
> [!NOTE]
|
||||||
|
> The first release tag is a special case since there is no previous release the action can reference to. For this case, there are 2 options:
|
||||||
> 1. When checking out the source via `git` (E.g.: `actions/checkout`), the action will use the first commit.
|
> 1. When checking out the source via `git` (E.g.: `actions/checkout`), the action will use the first commit.
|
||||||
> 2. Create a initial tag on the commit you want to begin a changelog from (for example `v0.0.1`).
|
> 2. Create a initial tag on the commit you want to begin a changelog from (for example `v0.0.1`).
|
||||||
|
|
||||||
> **Note**: By default not specifying `fromTag` or `toTag` will resolve `toTag` from either the `ref` or alternatively fallback to the latest tag from the git API. `fromTag` is resolved by sorting tags using [semver](https://semver.org/). Check the [configuration](#configuration-specification) for alternatives.
|
> [!NOTE]
|
||||||
|
> By default not specifying `fromTag` or `toTag` will resolve `toTag` from either the `ref` or alternatively fallback to the latest tag from the git API. `fromTag` is resolved by sorting tags using [semver](https://semver.org/). Check the [configuration](#configuration-specification) for alternatives.
|
||||||
|
|
||||||
> **Note**: If you are behind a corporate HTTP proxy, you can set the `https_proxy` environment variable to the proxy URL. For reference, please see the Octokit [documentation](https://github.com/octokit/octokit.js/#proxy-servers-nodejs-only).
|
> [!NOTE]
|
||||||
|
> If you are behind a corporate HTTP proxy, you can set the `https_proxy` environment variable to the proxy URL. For reference, please see the Octokit [documentation](https://github.com/octokit/octokit.js/#proxy-servers-nodejs-only).
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
@@ -192,11 +197,14 @@ The action supports flexible configuration options to modify vast areas of its b
|
|||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note** Defaults for the configuration can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts)
|
> [!NOTE]
|
||||||
|
> Defaults for the configuration can be found in the [configuration.ts](https://github.com/mikepenz/release-changelog-builder-action/blob/develop/src/configuration.ts)
|
||||||
|
|
||||||
> **Warning** It is required to have a `checkout` step prior to the changelog step if `configuration` is used, to allow the action to discover the configuration file. Use `configurationJson` as alternative.
|
> [!WARNING]
|
||||||
|
> It is required to have a `checkout` step prior to the changelog step if `configuration` is used, to allow the action to discover the configuration file. Use `configurationJson` as alternative.
|
||||||
|
|
||||||
> **Note** It is possible to provide the configuration as file and as json via the yml file. The order of config values used: `configurationJson` > `configuration` > `DefaultConfiguration`.
|
> [!NOTE]
|
||||||
|
> It is possible to provide the configuration as file and as json via the yml file. The order of config values used: `configurationJson` > `configuration` > `DefaultConfiguration`.
|
||||||
|
|
||||||
This configuration is a `JSON` in the following format. (The below showcases *example* configurations for all possible options. In most scenarios most of the settings will not be needed, and the defaults will be appropiate.)
|
This configuration is a `JSON` in the following format. (The below showcases *example* configurations for all possible options. In most scenarios most of the settings will not be needed, and the defaults will be appropiate.)
|
||||||
|
|
||||||
@@ -293,7 +301,8 @@ This configuration is a `JSON` in the following format. (The below showcases *ex
|
|||||||
|
|
||||||
Any section of the configuration can be omitted to have defaults apply.
|
Any section of the configuration can be omitted to have defaults apply.
|
||||||
|
|
||||||
> **Warning**: `ignore_labels` take precedence over category labels, allowing to specifically exclude certain PRs.
|
> [!WARNING]
|
||||||
|
> `ignore_labels` take precedence over category labels, allowing to specifically exclude certain PRs.
|
||||||
|
|
||||||
Please see the [Configuration Specification](#configuration-specification) for detailed descriptions on the offered configuration options.
|
Please see the [Configuration Specification](#configuration-specification) for detailed descriptions on the offered configuration options.
|
||||||
|
|
||||||
@@ -316,7 +325,8 @@ For advanced use cases additional settings can be provided to the action
|
|||||||
token: ${{ secrets.PAT }}
|
token: ${{ secrets.PAT }}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note**: All input values are optional. It is only required to provide the `token` either via the input, or as `env` variable.
|
> [!NOTE]
|
||||||
|
> All input values are optional. It is only required to provide the `token` either via the input, or as `env` variable.
|
||||||
|
|
||||||
| **Input** | **Description** |
|
| **Input** | **Description** |
|
||||||
|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
@@ -342,7 +352,8 @@ For advanced use cases additional settings can be provided to the action
|
|||||||
| `exportOnly` | When enabled, will result in only exporting the cache, without genearting a changelog. Default: false (Requires `exportCache` to be enabled) |
|
| `exportOnly` | When enabled, will result in only exporting the cache, without genearting a changelog. Default: false (Requires `exportCache` to be enabled) |
|
||||||
| `cache` | The file path to write/read the cache to/from. |
|
| `cache` | The file path to write/read the cache to/from. |
|
||||||
|
|
||||||
> **Warning**: `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repositories please use a PAT (Personal Access Token).
|
> [!WARNING]
|
||||||
|
> `${{ secrets.GITHUB_TOKEN }}` only grants rights to the current repository, for other repositories please use a PAT (Personal Access Token).
|
||||||
|
|
||||||
### PR Template placeholders
|
### PR Template placeholders
|
||||||
|
|
||||||
@@ -365,7 +376,8 @@ Table of supported placeholders allowed to be used in the `pr_template` configur
|
|||||||
| `#{{REVIEWERS}}` | GitHub Login names of specified reviewers, joined by `,`. Requires `fetchReviewers` to be enabled. |
|
| `#{{REVIEWERS}}` | GitHub Login names of specified reviewers, joined by `,`. Requires `fetchReviewers` to be enabled. |
|
||||||
| `#{{APPROVERS}}` | GitHub Login names of users who approved the PR, joined by `,`. |
|
| `#{{APPROVERS}}` | GitHub Login names of users who approved the PR, joined by `,`. |
|
||||||
|
|
||||||
> **Note**: `v4` updates the default placeholders format to `#{{}}`. The old format `${{}}` will be supported until v5 for backwards compatiblity.
|
> [!IMPORTANT]
|
||||||
|
> `v4` updates the default placeholders format to `#{{}}`. The old format `${{}}` will be supported until v5 for backwards compatiblity.
|
||||||
|
|
||||||
<details><summary><b>Array Placeholders</b></summary>
|
<details><summary><b>Array Placeholders</b></summary>
|
||||||
<p>
|
<p>
|
||||||
@@ -406,7 +418,6 @@ Similar to `REVIEWS`, `REFERENCED` PRs also offer special placeholders.
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Template placeholders
|
### Template placeholders
|
||||||
|
|
||||||
Table of supported placeholders allowed to be used in the `template` and `empty_template` (only supports placeholder marked for empty) configuration, to give additional control on defining the contents of the release notes / changelog.
|
Table of supported placeholders allowed to be used in the `template` and `empty_template` (only supports placeholder marked for empty) configuration, to give additional control on defining the contents of the release notes / changelog.
|
||||||
@@ -482,10 +493,10 @@ Table of descriptions for the `configuration.json` options to configure the resu
|
|||||||
| tag_resolver.transformer | Defines a regex transformer used to optionally transform the tag after the filter was applied. Allows to adjust the format to e.g. semver. |
|
| tag_resolver.transformer | Defines a regex transformer used to optionally transform the tag after the filter was applied. Allows to adjust the format to e.g. semver. |
|
||||||
| base_branches | The target branches for the merged PR, ingnores PRs with different target branch. Values can be a `regex`. Default: allow all base branches |
|
| base_branches | The target branches for the merged PR, ingnores PRs with different target branch. Values can be a `regex`. Default: allow all base branches |
|
||||||
| trim_values | Defines if all values inserted in templates are `trimmed`. Default: false |
|
| trim_values | Defines if all values inserted in templates are `trimmed`. Default: false |
|
||||||
|
### Custom placeholders 🧪
|
||||||
|
|
||||||
## Experimental 🧪
|
Starting with v3.2.0 the action provides a feature of defining `CUSTOM_PLACEHOLDERS`.
|
||||||
|
|
||||||
Starting with v3.2.0 the action provides an experimental feature of defining `CUSTOM_PLACEHOLDERS`.
|
|
||||||
Custom placeholders allow to extract values from any existing placeholder and insert them into the target template.
|
Custom placeholders allow to extract values from any existing placeholder and insert them into the target template.
|
||||||
|
|
||||||
<details><summary><b>Example</b></summary>
|
<details><summary><b>Example</b></summary>
|
||||||
@@ -530,6 +541,26 @@ Custom placeholders offer one new feature though. PR related placeholders can be
|
|||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Gitea support 🧪
|
||||||
|
|
||||||
|
Starting with v4.1.0 the action is also compatible with [gitea](https://github.com/go-gitea/gitea).
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> The API from gitea does not allow to retrieve the `diff` via its API, requiring the repo to be checked out
|
||||||
|
|
||||||
|
The API for gitea is equal to the one from GitHub, however it requires the `platform` to be specified.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
- name: Build Changelog
|
||||||
|
uses: https://github.com/mikepenz/release-changelog-builder-action@v4.1.0
|
||||||
|
with:
|
||||||
|
platform: "gitea" # gitea or github, default is github
|
||||||
|
commitMode: true
|
||||||
|
configuration: "configuration.json"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Do not change this
|
||||||
|
```
|
||||||
|
|
||||||
## Contribute 🧬
|
## Contribute 🧬
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -0,0 +1,793 @@
|
|||||||
|
import {mergeConfiguration, resolveConfiguration} from '../../src/utils'
|
||||||
|
import {ReleaseNotesBuilder} from '../../src/releaseNotesBuilder'
|
||||||
|
import {GiteaRepository} from '../../src/repositories/GiteaRepository'
|
||||||
|
|
||||||
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before starting testing, you should manually clone the repository
|
||||||
|
* cd /tmp && git clone https://gitea.com/mikepenz/sip
|
||||||
|
*
|
||||||
|
* (Forked from: https://gitea.com/jolheiser/sip)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const token = process.env.GITEA_TOKEN || ''
|
||||||
|
const workingDirectory = '/tmp/sip/'
|
||||||
|
const owner = 'jolheiser'
|
||||||
|
const repo = 'sip'
|
||||||
|
const configurationFile = 'configs/configuration_gitea.json'
|
||||||
|
|
||||||
|
it('[Gitea] Verify reviewers who approved are fetched and also release information', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null, // baseUrl
|
||||||
|
giteaRepository, // token
|
||||||
|
workingDirectory, // repoPath
|
||||||
|
owner, // user
|
||||||
|
repo, // repo
|
||||||
|
'v0.5.0', // fromTag
|
||||||
|
'master', // toTag
|
||||||
|
true, // includeOpen
|
||||||
|
false, // failOnError
|
||||||
|
false, // ignorePrePrelease
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
true, // enable to fetch reviewers
|
||||||
|
true, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration // configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 📦 Uncategorized
|
||||||
|
|
||||||
|
- Add attachment removal and change message -- (#36) [merged] ---
|
||||||
|
- Change to vanity URL -- (#37) [merged] ---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should match generated changelog (unspecified fromTag)', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
null,
|
||||||
|
'v0.1.1',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🧪 Upgrade
|
||||||
|
|
||||||
|
- Clean up and polish
|
||||||
|
- PR: #1
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
//
|
||||||
|
it('[Gitea] Should match generated changelog (unspecified tags)', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🚀 Features
|
||||||
|
|
||||||
|
- Add release attachments
|
||||||
|
- PR: #26
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should use empty placeholder', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'v0.1.1',
|
||||||
|
'v0.3.0',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🚀 Features
|
||||||
|
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Add create repo command
|
||||||
|
- PR: #13
|
||||||
|
- Add release support and CSV output
|
||||||
|
- PR: #16
|
||||||
|
|
||||||
|
## 🐛 Fixes
|
||||||
|
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should fill empty placeholders', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'v0.1.0',
|
||||||
|
'v0.4.0',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 🚀 Features
|
||||||
|
|
||||||
|
- Add create repo command
|
||||||
|
- PR: #13
|
||||||
|
- Add release support and CSV output
|
||||||
|
- PR: #16
|
||||||
|
- Add open functionality
|
||||||
|
- PR: #21
|
||||||
|
|
||||||
|
## 📦 Uncategorized
|
||||||
|
|
||||||
|
- Clean up and polish
|
||||||
|
- PR: #1
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
- Update Beaver and fix bugs
|
||||||
|
- PR: #6
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Changelog 0.2.0
|
||||||
|
- PR: #9
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
- Imp formatting
|
||||||
|
- PR: #17
|
||||||
|
- Update Gitea SDK and other modules
|
||||||
|
- PR: #19
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
|
||||||
|
|
||||||
|
- Clean up and polish
|
||||||
|
- PR: #1
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
- Update Beaver and fix bugs
|
||||||
|
- PR: #6
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Changelog 0.2.0
|
||||||
|
- PR: #9
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
- Imp formatting
|
||||||
|
- PR: #17
|
||||||
|
- Update Gitea SDK and other modules
|
||||||
|
- PR: #19
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
|
||||||
|
|
||||||
|
jolheiser
|
||||||
|
sip
|
||||||
|
v0.1.0
|
||||||
|
v0.4.0
|
||||||
|
https://gitea.com/jolheiser/sip/compare/v0.1.0...v0.4.0
|
||||||
|
3
|
||||||
|
12
|
||||||
|
0
|
||||||
|
36
|
||||||
|
1322
|
||||||
|
274
|
||||||
|
0
|
||||||
|
16`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should fill `template` placeholders', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'v0.1.0',
|
||||||
|
'v0.4.0',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 🚀 Features
|
||||||
|
|
||||||
|
- Add create repo command
|
||||||
|
- PR: #13
|
||||||
|
- Add release support and CSV output
|
||||||
|
- PR: #16
|
||||||
|
- Add open functionality
|
||||||
|
- PR: #21
|
||||||
|
|
||||||
|
## 📦 Uncategorized
|
||||||
|
|
||||||
|
- Clean up and polish
|
||||||
|
- PR: #1
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
- Update Beaver and fix bugs
|
||||||
|
- PR: #6
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Changelog 0.2.0
|
||||||
|
- PR: #9
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
- Imp formatting
|
||||||
|
- PR: #17
|
||||||
|
- Update Gitea SDK and other modules
|
||||||
|
- PR: #19
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
|
||||||
|
|
||||||
|
- Clean up and polish
|
||||||
|
- PR: #1
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
- Update Beaver and fix bugs
|
||||||
|
- PR: #6
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Changelog 0.2.0
|
||||||
|
- PR: #9
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
- Imp formatting
|
||||||
|
- PR: #17
|
||||||
|
- Update Gitea SDK and other modules
|
||||||
|
- PR: #19
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
|
||||||
|
|
||||||
|
jolheiser
|
||||||
|
sip
|
||||||
|
v0.1.0
|
||||||
|
v0.4.0
|
||||||
|
https://gitea.com/jolheiser/sip/compare/v0.1.0...v0.4.0
|
||||||
|
3
|
||||||
|
12
|
||||||
|
0
|
||||||
|
36
|
||||||
|
1322
|
||||||
|
274
|
||||||
|
0
|
||||||
|
16`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should fill `template` placeholders, ignore', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
||||||
|
configuration.categories.pop() // drop `uncategorized` category
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'v0.3.0',
|
||||||
|
'v0.5.0',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 🚀 Features
|
||||||
|
|
||||||
|
- Add open functionality
|
||||||
|
- PR: #21
|
||||||
|
|
||||||
|
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
- Update Gitea SDK
|
||||||
|
- PR: #23
|
||||||
|
- Update repo info
|
||||||
|
- PR: #24
|
||||||
|
- Add release attachments
|
||||||
|
- PR: #26
|
||||||
|
- Refactor
|
||||||
|
- PR: #29
|
||||||
|
|
||||||
|
|
||||||
|
jolheiser
|
||||||
|
sip
|
||||||
|
v0.3.0
|
||||||
|
v0.5.0
|
||||||
|
https://gitea.com/jolheiser/sip/compare/v0.3.0...v0.5.0
|
||||||
|
1
|
||||||
|
6
|
||||||
|
0
|
||||||
|
41
|
||||||
|
748
|
||||||
|
314
|
||||||
|
0
|
||||||
|
8`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Uncategorized category', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_uncategorized_category.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'v0.3.0',
|
||||||
|
'v0.5.0',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 🚀 Features
|
||||||
|
|
||||||
|
- Add open functionality
|
||||||
|
- PR: #21
|
||||||
|
|
||||||
|
## 📦 Uncategorized
|
||||||
|
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
- Update Gitea SDK
|
||||||
|
- PR: #23
|
||||||
|
- Update repo info
|
||||||
|
- PR: #24
|
||||||
|
- Add release attachments
|
||||||
|
- PR: #26
|
||||||
|
- Refactor
|
||||||
|
- PR: #29
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Uncategorized:
|
||||||
|
- Update modules
|
||||||
|
- PR: #20
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
- Update Gitea SDK
|
||||||
|
- PR: #23
|
||||||
|
- Update repo info
|
||||||
|
- PR: #24
|
||||||
|
- Add release attachments
|
||||||
|
- PR: #26
|
||||||
|
- Refactor
|
||||||
|
- PR: #29
|
||||||
|
|
||||||
|
|
||||||
|
Ignored:
|
||||||
|
|
||||||
|
|
||||||
|
6
|
||||||
|
0`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Verify commit based changelog', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'v0.3.0',
|
||||||
|
'v0.5.0',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
true, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 📦 Uncategorized
|
||||||
|
|
||||||
|
- Update modules (#20)
|
||||||
|
|
||||||
|
- Add open functionality (#21)
|
||||||
|
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0 (#22)
|
||||||
|
|
||||||
|
- Update Gitea SDK (#23)
|
||||||
|
|
||||||
|
- Update repo info (#24)
|
||||||
|
|
||||||
|
- Add release attachments (#26)
|
||||||
|
|
||||||
|
- Refactor (#29)
|
||||||
|
|
||||||
|
- Changelog 0.5.0 (#30)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Uncategorized:
|
||||||
|
- Update modules (#20)
|
||||||
|
|
||||||
|
- Add open functionality (#21)
|
||||||
|
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0 (#22)
|
||||||
|
|
||||||
|
- Update Gitea SDK (#23)
|
||||||
|
|
||||||
|
- Update repo info (#24)
|
||||||
|
|
||||||
|
- Add release attachments (#26)
|
||||||
|
|
||||||
|
- Refactor (#29)
|
||||||
|
|
||||||
|
- Changelog 0.5.0 (#30)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Ignored:
|
||||||
|
|
||||||
|
|
||||||
|
8
|
||||||
|
0`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Verify commit based changelog', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null,
|
||||||
|
giteaRepository,
|
||||||
|
workingDirectory,
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
'3e49adf6047960a03f53346bbececb3ce7e0809b',
|
||||||
|
'894a641ef86c444dccfa55eca457186b5e10da95',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
true, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(
|
||||||
|
`## 🚀 Features
|
||||||
|
|
||||||
|
- Add release attachments (#26)
|
||||||
|
- PR: #0
|
||||||
|
|
||||||
|
`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
// no open prs
|
||||||
|
it('[Gitea] Verify default inclusion of open PRs', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_including_open.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null, // baseUrl
|
||||||
|
giteaRepository, // token
|
||||||
|
workingDirectory, // repoPath
|
||||||
|
owner, // user
|
||||||
|
repo, // repo
|
||||||
|
'v0.5.0', // fromTag
|
||||||
|
'master', // toTag
|
||||||
|
true, // includeOpen
|
||||||
|
false, // failOnError
|
||||||
|
false, // ignorePrePrelease
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration // configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`
|
||||||
|
|
||||||
|
|
||||||
|
Uncategorized
|
||||||
|
- Add attachment removal and change message (#36) merged
|
||||||
|
- Change to vanity URL (#37) merged
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Open
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Verify custom categorisation of open PRs', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_excluding_open.json'))
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null, // baseUrl
|
||||||
|
giteaRepository, // token
|
||||||
|
workingDirectory, // repoPath
|
||||||
|
owner, // user
|
||||||
|
repo, // repo
|
||||||
|
'v0.5.0', // fromTag
|
||||||
|
'master', // toTag
|
||||||
|
true, // includeOpen
|
||||||
|
false, // failOnError
|
||||||
|
false, // ignorePrePrelease
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
false, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration // configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(``)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Fetch release information', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
||||||
|
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null, // baseUrl
|
||||||
|
giteaRepository, // token
|
||||||
|
workingDirectory, // repoPath
|
||||||
|
owner, // user
|
||||||
|
repo, // repo
|
||||||
|
'v0.5.0', // fromTag
|
||||||
|
'master', // toTag
|
||||||
|
true, // includeOpen
|
||||||
|
false, // failOnError
|
||||||
|
false, // ignorePrePrelease
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
true, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration // configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`v0.5.0-2020-09-17T16:34:40.000Z
|
||||||
|
master-2020-09-21T19:30:21.000Z
|
||||||
|
4`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Fetch release information for non existing tag / release', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
||||||
|
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
|
||||||
|
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null, // baseUrl
|
||||||
|
giteaRepository, // token
|
||||||
|
workingDirectory, // repoPath
|
||||||
|
owner, // user
|
||||||
|
repo, // repo
|
||||||
|
'v0.5.0', // fromTag
|
||||||
|
'master', // toTag
|
||||||
|
true, // includeOpen
|
||||||
|
false, // failOnError
|
||||||
|
false, // ignorePrePrelease
|
||||||
|
false, // enable to fetch via commits
|
||||||
|
false, // enable to fetch reviewers
|
||||||
|
true, // enable to fetch tag release information
|
||||||
|
false, // enable to fetch reviews
|
||||||
|
false, // enable commitMode
|
||||||
|
false, // enable exportCache
|
||||||
|
false, // enable exportOnly
|
||||||
|
null, // path to the cache
|
||||||
|
configuration // configuration
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`v0.5.0-2020-09-17T16:34:40.000Z
|
||||||
|
master-2020-09-21T19:30:21.000Z
|
||||||
|
4`)
|
||||||
|
})
|
||||||
@@ -0,0 +1,349 @@
|
|||||||
|
import {checkExportedData, mergeConfiguration, resolveConfiguration} from '../../src/utils'
|
||||||
|
import {buildChangelog} from '../../src/transform'
|
||||||
|
import {pullData} from '../../src/pr-collector/prCollector'
|
||||||
|
import {GiteaRepository} from '../../src/repositories/GiteaRepository'
|
||||||
|
|
||||||
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
|
// load octokit instance
|
||||||
|
const enablePullData = false
|
||||||
|
/**
|
||||||
|
* if false -> use cache for data
|
||||||
|
* Use the below snippet to export the cache:
|
||||||
|
*
|
||||||
|
* writeCacheData({
|
||||||
|
* mergedPullRequests: data.mergedPullRequests,
|
||||||
|
* diffInfo: data.diffInfo,
|
||||||
|
* options
|
||||||
|
* }, 'caches/gitea_rcba_0.1.0-master_cache.json')
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Before starting testing, you should manually clone the repository
|
||||||
|
* cd /tmp && git clone https://gitea.com/mikepenz/sip
|
||||||
|
*
|
||||||
|
* (Forked from: https://gitea.com/jolheiser/sip)
|
||||||
|
*/
|
||||||
|
|
||||||
|
const token = process.env.GITEA_TOKEN || ''
|
||||||
|
const workingDirectory = '/tmp/sip/'
|
||||||
|
const owner = 'jolheiser'
|
||||||
|
const repo = 'sip'
|
||||||
|
const giteaRepository = new GiteaRepository(token, undefined, workingDirectory)
|
||||||
|
const configurationFile = 'configs/configuration_gitea.json'
|
||||||
|
it('[Gitea] Should have changelog (tags)', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
fromTag: {name: 'v0.5.0'},
|
||||||
|
toTag: {name: 'master'},
|
||||||
|
includeOpen: false,
|
||||||
|
failOnError: false,
|
||||||
|
fetchViaCommits: true,
|
||||||
|
fetchReviewers: false,
|
||||||
|
fetchReleaseInformation: false,
|
||||||
|
fetchReviews: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration,
|
||||||
|
repositoryUtils: giteaRepository
|
||||||
|
}
|
||||||
|
let data: any
|
||||||
|
if (enablePullData) {
|
||||||
|
data = await pullData(giteaRepository, options)
|
||||||
|
} else {
|
||||||
|
data = checkExportedData(false, 'caches/gitea_rcba_0.5.0-master_cache.json')
|
||||||
|
}
|
||||||
|
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🚀 Features
|
||||||
|
|
||||||
|
- Add attachment removal and change message
|
||||||
|
- PR: #36
|
||||||
|
|
||||||
|
## 🐛 Fixes
|
||||||
|
|
||||||
|
- Fix drone-gitea-main
|
||||||
|
- PR: #38
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should match generated changelog (tags)', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
const options = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
fromTag: {name: 'v0.5.0'},
|
||||||
|
toTag: {name: 'master'},
|
||||||
|
includeOpen: false,
|
||||||
|
failOnError: false,
|
||||||
|
fetchViaCommits: true,
|
||||||
|
fetchReviewers: false,
|
||||||
|
fetchReleaseInformation: false,
|
||||||
|
fetchReviews: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration,
|
||||||
|
repositoryUtils: giteaRepository
|
||||||
|
}
|
||||||
|
let data: any
|
||||||
|
if (enablePullData) {
|
||||||
|
data = await pullData(giteaRepository, options)
|
||||||
|
} else {
|
||||||
|
data = checkExportedData(false, 'caches/gitea_rcba_0.5.0-master_cache.json')
|
||||||
|
}
|
||||||
|
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🚀 Features
|
||||||
|
|
||||||
|
- Add attachment removal and change message
|
||||||
|
- PR: #36
|
||||||
|
|
||||||
|
## 🐛 Fixes
|
||||||
|
|
||||||
|
- Fix drone-gitea-main
|
||||||
|
- PR: #38
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should match generated changelog (refs)', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_all_placeholders.json'))
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
fromTag: {name: '3e49adf6047960a03f53346bbececb3ce7e0809b'},
|
||||||
|
toTag: {name: '894a641ef86c444dccfa55eca457186b5e10da95'},
|
||||||
|
includeOpen: false,
|
||||||
|
failOnError: false,
|
||||||
|
fetchViaCommits: true,
|
||||||
|
fetchReviewers: false,
|
||||||
|
fetchReleaseInformation: false,
|
||||||
|
fetchReviews: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration,
|
||||||
|
repositoryUtils: giteaRepository
|
||||||
|
}
|
||||||
|
let data: any
|
||||||
|
if (enablePullData) {
|
||||||
|
data = await pullData(giteaRepository, options)
|
||||||
|
} else {
|
||||||
|
data = checkExportedData(false, 'caches/gitea_rcba_3e49adf-894a64_cache.json')
|
||||||
|
}
|
||||||
|
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 📦 Uncategorized
|
||||||
|
|
||||||
|
Add release attachments
|
||||||
|
26
|
||||||
|
https://gitea.com/jolheiser/sip/pulls/26
|
||||||
|
2020-09-16T18:07:32.000Z
|
||||||
|
jolheiser
|
||||||
|
enhancement
|
||||||
|
0.5.0
|
||||||
|
Resolves #25
|
||||||
|
|
||||||
|
|
||||||
|
Refactor
|
||||||
|
29
|
||||||
|
https://gitea.com/jolheiser/sip/pulls/29
|
||||||
|
2020-09-17T16:25:11.000Z
|
||||||
|
jolheiser
|
||||||
|
enhancement
|
||||||
|
0.5.0
|
||||||
|
Fixes #27
|
||||||
|
|
||||||
|
Fixes #28
|
||||||
|
|
||||||
|
This PR refactors and cleans up packages.
|
||||||
|
|
||||||
|
It also scans CLI flags into variables for fewer footguns.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should match generated changelog and replace all occurrences (refs)', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_replace_all_placeholders.json'))
|
||||||
|
const options = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
fromTag: {name: '3e49adf6047960a03f53346bbececb3ce7e0809b'},
|
||||||
|
toTag: {name: '894a641ef86c444dccfa55eca457186b5e10da95'},
|
||||||
|
includeOpen: false,
|
||||||
|
failOnError: false,
|
||||||
|
fetchViaCommits: true,
|
||||||
|
fetchReviewers: false,
|
||||||
|
fetchReleaseInformation: false,
|
||||||
|
fetchReviews: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration,
|
||||||
|
repositoryUtils: giteaRepository
|
||||||
|
}
|
||||||
|
let data: any
|
||||||
|
if (enablePullData) {
|
||||||
|
data = await pullData(giteaRepository, options)
|
||||||
|
} else {
|
||||||
|
data = checkExportedData(false, 'caches/gitea_rcba_3e49adf-894a64_cache.json')
|
||||||
|
}
|
||||||
|
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 📦 Uncategorized
|
||||||
|
|
||||||
|
Add release attachments
|
||||||
|
Add release attachments
|
||||||
|
26
|
||||||
|
https://gitea.com/jolheiser/sip/pulls/26
|
||||||
|
2020-09-16T18:07:32.000Z
|
||||||
|
jolheiser
|
||||||
|
jolheiser
|
||||||
|
enhancement
|
||||||
|
0.5.0
|
||||||
|
Resolves #25
|
||||||
|
|
||||||
|
|
||||||
|
Refactor
|
||||||
|
Refactor
|
||||||
|
29
|
||||||
|
https://gitea.com/jolheiser/sip/pulls/29
|
||||||
|
2020-09-17T16:25:11.000Z
|
||||||
|
jolheiser
|
||||||
|
jolheiser
|
||||||
|
enhancement
|
||||||
|
0.5.0
|
||||||
|
Fixes #27
|
||||||
|
|
||||||
|
Fixes #28
|
||||||
|
|
||||||
|
This PR refactors and cleans up packages.
|
||||||
|
|
||||||
|
It also scans CLI flags into variables for fewer footguns.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should match ordered ASC', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', configurationFile))
|
||||||
|
configuration.categories.pop() // drop `uncategorized` category
|
||||||
|
const options = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
fromTag: {name: 'v0.1.0'},
|
||||||
|
toTag: {name: 'master'},
|
||||||
|
includeOpen: false,
|
||||||
|
failOnError: false,
|
||||||
|
fetchViaCommits: false,
|
||||||
|
fetchReviewers: false,
|
||||||
|
fetchReleaseInformation: false,
|
||||||
|
fetchReviews: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration,
|
||||||
|
repositoryUtils: giteaRepository
|
||||||
|
}
|
||||||
|
let data: any
|
||||||
|
if (enablePullData) {
|
||||||
|
data = await pullData(giteaRepository, options)
|
||||||
|
} else {
|
||||||
|
data = checkExportedData(false, 'caches/gitea_rcba_0.1.0-master_cache.json')
|
||||||
|
}
|
||||||
|
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🚀 Features
|
||||||
|
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Add create repo command
|
||||||
|
- PR: #13
|
||||||
|
- Add release support and CSV output
|
||||||
|
- PR: #16
|
||||||
|
- Add open functionality
|
||||||
|
- PR: #21
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
- Add release attachments
|
||||||
|
- PR: #26
|
||||||
|
- Add attachment removal and change message
|
||||||
|
- PR: #36
|
||||||
|
|
||||||
|
## 🐛 Fixes
|
||||||
|
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('[Gitea] Should match ordered DESC', async () => {
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_gitea_desc.json'))
|
||||||
|
configuration.categories.pop() // drop `uncategorized` category
|
||||||
|
const options = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
fromTag: {name: 'v0.1.0'},
|
||||||
|
toTag: {name: 'master'},
|
||||||
|
includeOpen: false,
|
||||||
|
failOnError: false,
|
||||||
|
fetchViaCommits: false,
|
||||||
|
fetchReviewers: false,
|
||||||
|
fetchReleaseInformation: false,
|
||||||
|
fetchReviews: false,
|
||||||
|
commitMode: false,
|
||||||
|
configuration,
|
||||||
|
repositoryUtils: giteaRepository
|
||||||
|
}
|
||||||
|
let data: any
|
||||||
|
if (enablePullData) {
|
||||||
|
data = await pullData(giteaRepository, options)
|
||||||
|
} else {
|
||||||
|
data = checkExportedData(false, 'caches/gitea_rcba_0.1.0-master_cache.json')
|
||||||
|
}
|
||||||
|
const changeLog = buildChangelog(data!.diffInfo, data!.mergedPullRequests, options)
|
||||||
|
console.log(changeLog)
|
||||||
|
expect(changeLog).toStrictEqual(`## 🚀 Features
|
||||||
|
|
||||||
|
- Add attachment removal and change message
|
||||||
|
- PR: #36
|
||||||
|
- Add release attachments
|
||||||
|
- PR: #26
|
||||||
|
- Add changelog for 0.3.0 and 0.4.0
|
||||||
|
- PR: #22
|
||||||
|
- Add open functionality
|
||||||
|
- PR: #21
|
||||||
|
- Add release support and CSV output
|
||||||
|
- PR: #16
|
||||||
|
- Add create repo command
|
||||||
|
- PR: #13
|
||||||
|
- Add qualifier module
|
||||||
|
- PR: #10
|
||||||
|
- Add search filters
|
||||||
|
- PR: #8
|
||||||
|
- Add Drone and releases
|
||||||
|
- PR: #2
|
||||||
|
|
||||||
|
## 🐛 Fixes
|
||||||
|
|
||||||
|
- Fix Drone release
|
||||||
|
- PR: #14
|
||||||
|
- Fix PR head nil panic
|
||||||
|
- PR: #7
|
||||||
|
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I delete these test cases about gitea
|
||||||
|
* Should match ordered by title ASC
|
||||||
|
* Should match ordered by title DESC
|
||||||
|
* Should ignore PRs not merged into develop branch
|
||||||
|
*/
|
||||||
@@ -6,17 +6,19 @@ import * as fs from 'fs'
|
|||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
test('missing values should result in failure', () => {
|
test('missing values should result in failure', () => {
|
||||||
|
expect.assertions(1)
|
||||||
|
|
||||||
process.env['GITHUB_WORKSPACE'] = '.'
|
process.env['GITHUB_WORKSPACE'] = '.'
|
||||||
process.env['INPUT_CONFIGURATION'] = 'configuration.json'
|
process.env['INPUT_OWNER'] = undefined
|
||||||
|
process.env['INPUT_CONFIGURATION'] = 'configs/configuration.json'
|
||||||
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
||||||
const options: cp.ExecSyncOptions = {
|
const options: cp.ExecSyncOptions = {
|
||||||
env: process.env
|
env: process.env
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
cp.execSync(`node ${ip}`, options).toString()
|
cp.execSync(`node ${ip}`, options).toString()
|
||||||
fail('Should not succeed, because values miss')
|
} catch (error: any) {
|
||||||
} catch (error) {
|
expect(true).toBe(true)
|
||||||
console.log(`correctly failed due to: ${error}`)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -27,6 +29,7 @@ test('complete input should succeed', () => {
|
|||||||
process.env['INPUT_REPO'] = 'release-changelog-builder-action'
|
process.env['INPUT_REPO'] = 'release-changelog-builder-action'
|
||||||
process.env['INPUT_FROMTAG'] = 'v0.3.0'
|
process.env['INPUT_FROMTAG'] = 'v0.3.0'
|
||||||
process.env['INPUT_TOTAG'] = 'v0.5.0'
|
process.env['INPUT_TOTAG'] = 'v0.5.0'
|
||||||
|
process.env['INPUT_CACHE'] = 'caches/rcba_0.3.0-0.5.0_cache.json'
|
||||||
|
|
||||||
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
||||||
const options: cp.ExecSyncOptions = {
|
const options: cp.ExecSyncOptions = {
|
||||||
@@ -45,6 +48,7 @@ test('should write result to file', () => {
|
|||||||
process.env['INPUT_FROMTAG'] = 'v0.3.0'
|
process.env['INPUT_FROMTAG'] = 'v0.3.0'
|
||||||
process.env['INPUT_TOTAG'] = 'v0.5.0'
|
process.env['INPUT_TOTAG'] = 'v0.5.0'
|
||||||
process.env['INPUT_OUTPUTFILE'] = 'test.md'
|
process.env['INPUT_OUTPUTFILE'] = 'test.md'
|
||||||
|
process.env['INPUT_CACHE'] = 'caches/rcba_0.3.0-0.5.0_cache.json'
|
||||||
|
|
||||||
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
||||||
const options: cp.ExecSyncOptions = {
|
const options: cp.ExecSyncOptions = {
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
import {mergeConfiguration, resolveConfiguration} from '../src/utils'
|
import {mergeConfiguration, resolveConfiguration} from '../src/utils'
|
||||||
import {ReleaseNotesBuilder} from '../src/releaseNotesBuilder'
|
import {ReleaseNotesBuilder} from '../src/releaseNotesBuilder'
|
||||||
|
import {GithubRepository} from '../src/repositories/GithubRepository'
|
||||||
|
|
||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
it('Should match generated changelog (unspecified fromTag)', async () => {
|
const token = process.env.GITHUB_TOKEN || ''
|
||||||
|
const githubRepository = new GithubRepository(token, undefined, '.')
|
||||||
|
it('[Github] Should match generated changelog (unspecified fromTag)', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -37,11 +40,11 @@ it('Should match generated changelog (unspecified fromTag)', async () => {
|
|||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should match generated changelog (unspecified tags)', async () => {
|
it('[Github] Should match generated changelog (unspecified tags)', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'action-junit-report-legacy',
|
'action-junit-report-legacy',
|
||||||
@@ -66,11 +69,11 @@ it('Should match generated changelog (unspecified tags)', async () => {
|
|||||||
expect(changeLog).toStrictEqual(`## 🐛 Fixes\n\n- Stacktrace Data can be an array\n - PR: #39\n\n`)
|
expect(changeLog).toStrictEqual(`## 🐛 Fixes\n\n- Stacktrace Data can be an array\n - PR: #39\n\n`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should use empty placeholder', async () => {
|
it('[Github] Should use empty placeholder', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -95,11 +98,11 @@ it('Should use empty placeholder', async () => {
|
|||||||
expect(changeLog).toStrictEqual(`- no changes`)
|
expect(changeLog).toStrictEqual(`- no changes`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fill empty placeholders', async () => {
|
it('[Github] Should fill empty placeholders', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -126,11 +129,11 @@ it('Should fill empty placeholders', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fill `template` placeholders', async () => {
|
it('[Github] Should fill `template` placeholders', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -157,12 +160,12 @@ it('Should fill `template` placeholders', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should fill `template` placeholders, ignore', async () => {
|
it('[Github] Should fill `template` placeholders, ignore', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_empty_all_placeholders.json'))
|
||||||
configuration.categories.pop() // drop `uncategorized` category
|
configuration.categories.pop() // drop `uncategorized` category
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -189,11 +192,11 @@ it('Should fill `template` placeholders, ignore', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Uncategorized category', async () => {
|
it('[Github] Uncategorized category', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_uncategorized_category.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_uncategorized_category.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -220,11 +223,11 @@ it('Uncategorized category', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Verify commit based changelog', async () => {
|
it('[Github] Verify commit based changelog', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'mikepenz',
|
'mikepenz',
|
||||||
'release-changelog-builder-action',
|
'release-changelog-builder-action',
|
||||||
@@ -251,11 +254,11 @@ it('Verify commit based changelog', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Verify commit based changelog, with emoji categorisation', async () => {
|
it('[Github] Verify commit based changelog, with emoji categorisation', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits_emoji.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_commits_emoji.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null,
|
null,
|
||||||
null,
|
githubRepository,
|
||||||
'.',
|
'.',
|
||||||
'theapache64',
|
'theapache64',
|
||||||
'stackzy',
|
'stackzy',
|
||||||
@@ -282,11 +285,11 @@ it('Verify commit based changelog, with emoji categorisation', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Verify default inclusion of open PRs', async () => {
|
it('[Github] Verify default inclusion of open PRs', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_including_open.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_including_open.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null, // baseUrl
|
null, // baseUrl
|
||||||
null, // token
|
githubRepository, // token
|
||||||
'.', // repoPath
|
'.', // repoPath
|
||||||
'mikepenz', // user
|
'mikepenz', // user
|
||||||
'release-changelog-builder-action-playground', // repo
|
'release-changelog-builder-action-playground', // repo
|
||||||
@@ -313,11 +316,11 @@ it('Verify default inclusion of open PRs', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Verify custom categorisation of open PRs', async () => {
|
it('[Github] Verify custom categorisation of open PRs', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_excluding_open.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_excluding_open.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null, // baseUrl
|
null, // baseUrl
|
||||||
null, // token
|
githubRepository, // token
|
||||||
'.', // repoPath
|
'.', // repoPath
|
||||||
'mikepenz', // user
|
'mikepenz', // user
|
||||||
'release-changelog-builder-action-playground', // repo
|
'release-changelog-builder-action-playground', // repo
|
||||||
@@ -344,11 +347,11 @@ it('Verify custom categorisation of open PRs', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Verify reviewers who approved are fetched and also release information', async () => {
|
it('[Github] Verify reviewers who approved are fetched and also release information', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null, // baseUrl
|
null, // baseUrl
|
||||||
null, // token
|
githubRepository, // token
|
||||||
'.', // repoPath
|
'.', // repoPath
|
||||||
'mikepenz', // user
|
'mikepenz', // user
|
||||||
'release-changelog-builder-action-playground', // repo
|
'release-changelog-builder-action-playground', // repo
|
||||||
@@ -375,12 +378,12 @@ it('Verify reviewers who approved are fetched and also release information', asy
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Fetch release information', async () => {
|
it('[Github] Fetch release information', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
||||||
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
|
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null, // baseUrl
|
null, // baseUrl
|
||||||
null, // token
|
githubRepository, // token
|
||||||
'.', // repoPath
|
'.', // repoPath
|
||||||
'mikepenz', // user
|
'mikepenz', // user
|
||||||
'release-changelog-builder-action-playground', // repo
|
'release-changelog-builder-action-playground', // repo
|
||||||
@@ -405,12 +408,12 @@ it('Fetch release information', async () => {
|
|||||||
expect(changeLog).toStrictEqual(`2.0.0-2022-04-08T07:52:40.000Z\n3.0.0-a01-2022-07-26T14:28:36.000Z\n109`)
|
expect(changeLog).toStrictEqual(`2.0.0-2022-04-08T07:52:40.000Z\n3.0.0-a01-2022-07-26T14:28:36.000Z\n109`)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Fetch release information for non existing tag / release', async () => {
|
it('[Github] Fetch release information for non existing tag / release', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs_test/configuration_approvers.json'))
|
||||||
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
|
configuration.template = '#{{FROM_TAG}}-#{{FROM_TAG_DATE}}\n#{{TO_TAG}}-#{{TO_TAG_DATE}}\n#{{DAYS_SINCE}}'
|
||||||
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
null, // baseUrl
|
null, // baseUrl
|
||||||
null, // token
|
githubRepository, // token
|
||||||
'.', // repoPath
|
'.', // repoPath
|
||||||
'mikepenz', // user
|
'mikepenz', // user
|
||||||
'release-changelog-builder-action-playground', // repo
|
'release-changelog-builder-action-playground', // repo
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
import {checkExportedData, mergeConfiguration, resolveConfiguration} from '../src/utils'
|
import {checkExportedData, mergeConfiguration, resolveConfiguration} from '../src/utils'
|
||||||
import {Octokit} from '@octokit/rest'
|
|
||||||
import {buildChangelog} from '../src/transform'
|
import {buildChangelog} from '../src/transform'
|
||||||
import {pullData} from '../src/pr-collector/prCollector'
|
import {pullData} from '../src/pr-collector/prCollector'
|
||||||
import {Data} from '../src/releaseNotesBuilder'
|
import {GithubRepository} from '../src/repositories/GithubRepository'
|
||||||
|
|
||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
// load octokit instance
|
// load octokit instance
|
||||||
const enablePullData = false // if false -> use cache for data
|
const enablePullData = false // if false -> use cache for data
|
||||||
const octokit = new Octokit({
|
|
||||||
auth: `token ${process.env.GITHUB_TOKEN}`
|
|
||||||
})
|
|
||||||
|
|
||||||
|
const token = process.env.GITHUB_TOKEN || ''
|
||||||
|
const githubRepository = new GithubRepository(token, undefined, '.')
|
||||||
it('Should have empty changelog (tags)', async () => {
|
it('Should have empty changelog (tags)', async () => {
|
||||||
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration.json'))
|
||||||
|
|
||||||
@@ -27,11 +25,12 @@ it('Should have empty changelog (tags)', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_0.0.2-0.0.3_cache.json')
|
data = checkExportedData(false, 'caches/rcba_0.0.2-0.0.3_cache.json')
|
||||||
}
|
}
|
||||||
@@ -54,11 +53,12 @@ it('Should match generated changelog (tags)', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_0.0.1-0.0.3_cache.json')
|
data = checkExportedData(false, 'caches/rcba_0.0.1-0.0.3_cache.json')
|
||||||
}
|
}
|
||||||
@@ -87,11 +87,12 @@ it('Should match generated changelog (refs)', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_5ec7a2-fa3788_cache.json')
|
data = checkExportedData(false, 'caches/rcba_5ec7a2-fa3788_cache.json')
|
||||||
}
|
}
|
||||||
@@ -127,11 +128,12 @@ it('Should match generated changelog and replace all occurrences (refs)', async
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_5ec7a2-fa3788_cache.json')
|
data = checkExportedData(false, 'caches/rcba_5ec7a2-fa3788_cache.json')
|
||||||
}
|
}
|
||||||
@@ -170,11 +172,12 @@ it('Should match ordered ASC', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
||||||
}
|
}
|
||||||
@@ -198,11 +201,12 @@ it('Should match ordered DESC', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
||||||
}
|
}
|
||||||
@@ -225,11 +229,12 @@ it('Should match ordered by title ASC', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
||||||
}
|
}
|
||||||
@@ -254,11 +259,12 @@ it('Should match ordered by title DESC', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
data = checkExportedData(false, 'caches/rcba_0.3.0-0.5.0_cache.json')
|
||||||
}
|
}
|
||||||
@@ -283,11 +289,12 @@ it('Should ignore PRs not merged into develop branch', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_1.3.1-1.4.0_base_develop_cache.json')
|
data = checkExportedData(false, 'caches/rcba_1.3.1-1.4.0_base_develop_cache.json')
|
||||||
}
|
}
|
||||||
@@ -310,11 +317,12 @@ it('Should ignore PRs not merged into main branch', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration
|
configuration,
|
||||||
|
repositoryUtils: githubRepository
|
||||||
}
|
}
|
||||||
let data: any
|
let data: any
|
||||||
if (enablePullData) {
|
if (enablePullData) {
|
||||||
data = await pullData(octokit, options)
|
data = await pullData(githubRepository, options)
|
||||||
} else {
|
} else {
|
||||||
data = checkExportedData(false, 'caches/rcba_1.3.1-1.4.0_base_main_cache.json')
|
data = checkExportedData(false, 'caches/rcba_1.3.1-1.4.0_base_main_cache.json')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {TagInfo, filterTags, prepareAndSortTags} from '../src/pr-collector/tags'
|
import {filterTags, prepareAndSortTags, TagInfo} from '../src/pr-collector/tags'
|
||||||
|
|
||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import moment from 'moment'
|
|||||||
import {Configuration, DefaultConfiguration} from '../src/configuration'
|
import {Configuration, DefaultConfiguration} from '../src/configuration'
|
||||||
import {PullRequestInfo} from '../src/pr-collector/pullRequests'
|
import {PullRequestInfo} from '../src/pr-collector/pullRequests'
|
||||||
import {DefaultDiffInfo} from '../src/pr-collector/commits'
|
import {DefaultDiffInfo} from '../src/pr-collector/commits'
|
||||||
|
import {GithubRepository} from '../src/repositories/GithubRepository'
|
||||||
|
|
||||||
jest.setTimeout(180000)
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
@@ -437,6 +438,7 @@ it('Use empty_content for empty category', async () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const repositoryUtils = new GithubRepository(process.env.GITEA_TOKEN || '', undefined, '.')
|
||||||
it('Commit SHA-1 in commitMode', async () => {
|
it('Commit SHA-1 in commitMode', async () => {
|
||||||
const customConfig = Object.assign({}, DefaultConfiguration)
|
const customConfig = Object.assign({}, DefaultConfiguration)
|
||||||
customConfig.sort = 'DESC'
|
customConfig.sort = 'DESC'
|
||||||
@@ -453,7 +455,8 @@ it('Commit SHA-1 in commitMode', async () => {
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: true,
|
commitMode: true,
|
||||||
configuration: customConfig
|
configuration: customConfig,
|
||||||
|
repositoryUtils: repositoryUtils
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(resultChangelog).toStrictEqual(`## 🚀 Features\n\nsha1-3\nsha1-1\n\n## 🐛 Fixes\n\nsha1-3\nsha1-2\n\n`)
|
expect(resultChangelog).toStrictEqual(`## 🚀 Features\n\nsha1-3\nsha1-1\n\n## 🐛 Fixes\n\nsha1-3\nsha1-2\n\n`)
|
||||||
@@ -474,7 +477,8 @@ it('Release Diff', async () => {
|
|||||||
fetchReleaseInformation: true,
|
fetchReleaseInformation: true,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: true,
|
commitMode: true,
|
||||||
configuration: customConfig
|
configuration: customConfig,
|
||||||
|
repositoryUtils: repositoryUtils
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(resultChangelog).toStrictEqual(`https://github.com/mikepenz/release-changelog-builder-action/compare/v2.8.0...v2.8.1\n`)
|
expect(resultChangelog).toStrictEqual(`https://github.com/mikepenz/release-changelog-builder-action/compare/v2.8.0...v2.8.1\n`)
|
||||||
@@ -678,6 +682,7 @@ function buildChangelogTest(config: Configuration, prs: PullRequestInfo[]): stri
|
|||||||
fetchReleaseInformation: false,
|
fetchReleaseInformation: false,
|
||||||
fetchReviews: false,
|
fetchReviews: false,
|
||||||
commitMode: false,
|
commitMode: false,
|
||||||
configuration: config
|
configuration: config,
|
||||||
|
repositoryUtils: repositoryUtils
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ inputs:
|
|||||||
default: "false"
|
default: "false"
|
||||||
cache:
|
cache:
|
||||||
description: 'Provide the cache of a previous run. Allows to re-use collected information multiple times to generate different release notes. Requires `exportCache` to be enabled for the previous run.'
|
description: 'Provide the cache of a previous run. Allows to re-use collected information multiple times to generate different release notes. Requires `exportCache` to be enabled for the previous run.'
|
||||||
|
platform:
|
||||||
|
description: 'Defines the platform the action is run on. Available options: [`github`, `gitea`]. Defaults to `github`.'
|
||||||
|
default: "github"
|
||||||
outputs:
|
outputs:
|
||||||
changelog:
|
changelog:
|
||||||
description: The built release changelog built from the merged pull requests
|
description: The built release changelog built from the merged pull requests
|
||||||
|
|||||||
@@ -0,0 +1,708 @@
|
|||||||
|
{
|
||||||
|
"mergedPullRequests": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"title": "Clean up and polish",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/1",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "20df4b7f69f8dc609e98e3274739b49dc756884c",
|
||||||
|
"mergedAt": "2020-02-18T05:27:54.000Z",
|
||||||
|
"mergeCommitSha": "427ecdb7f1f4e289cb820ce2fbafe158b9b30012",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.1.1",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-18T05:27:13.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"title": "Add Drone and releases",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/2",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "427ecdb7f1f4e289cb820ce2fbafe158b9b30012",
|
||||||
|
"mergedAt": "2020-02-18T15:51:14.000Z",
|
||||||
|
"mergeCommitSha": "5929bebe01e7b8c7c57b3c8fdfd41d4038bb85a1",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.0",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-18T15:41:58.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 6,
|
||||||
|
"title": "Update Beaver and fix bugs",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/6",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "5929bebe01e7b8c7c57b3c8fdfd41d4038bb85a1",
|
||||||
|
"mergedAt": "2020-02-27T02:53:14.000Z",
|
||||||
|
"mergeCommitSha": "bb773780df3488204df93228bdd72eb59418029b",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"bug"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.0",
|
||||||
|
"body": "Fixes #3 \nFixes #4 \nFixes #5",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-27T02:45:46.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 7,
|
||||||
|
"title": "Fix PR head nil panic",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/7",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "bb773780df3488204df93228bdd72eb59418029b",
|
||||||
|
"mergedAt": "2020-02-27T03:03:34.000Z",
|
||||||
|
"mergeCommitSha": "1956062791dae3e66c0c11d6fa86c59b031e51ee",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"bug"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.0",
|
||||||
|
"body": "When checking PR status, retrieved PRs may have a nil head if the branch has been deleted.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-27T03:01:09.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 8,
|
||||||
|
"title": "Add search filters",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/8",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "1956062791dae3e66c0c11d6fa86c59b031e51ee",
|
||||||
|
"mergedAt": "2020-02-27T04:58:04.000Z",
|
||||||
|
"mergeCommitSha": "df58f223f25edd30ce8d15328d9d99fc9f98954b",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.0",
|
||||||
|
"body": "Adds search filters for state, author, labels, and milestone\n\nCheck the updated README for more details.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-27T04:39:37.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 9,
|
||||||
|
"title": "Changelog 0.2.0",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/9",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "df58f223f25edd30ce8d15328d9d99fc9f98954b",
|
||||||
|
"mergedAt": "2020-02-27T05:20:31.000Z",
|
||||||
|
"mergeCommitSha": "222dcf402b1cc0b57dbd4e2e9bc34196410c8a6b",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"docs"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.0",
|
||||||
|
"body": "As title",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-27T05:17:31.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 10,
|
||||||
|
"title": "Add qualifier module",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/10",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "222dcf402b1cc0b57dbd4e2e9bc34196410c8a6b",
|
||||||
|
"mergedAt": "2020-03-06T04:18:38.000Z",
|
||||||
|
"mergeCommitSha": "4490cc9888b4e39e14ce1c8fe9bdf64de348de71",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.1",
|
||||||
|
"body": "Better support for search query qualifiers",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-02-28T03:33:43.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 13,
|
||||||
|
"title": "Add create repo command",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/13",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "4490cc9888b4e39e14ce1c8fe9bdf64de348de71",
|
||||||
|
"mergedAt": "2020-03-06T04:21:58.000Z",
|
||||||
|
"mergeCommitSha": "03fb319d3989c68a39c0652d8ff972e0957c5e6c",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"feature"
|
||||||
|
],
|
||||||
|
"milestone": "0.3.0",
|
||||||
|
"body": "Resolves #12",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-03-06T04:17:46.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 14,
|
||||||
|
"title": "Fix Drone release",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/14",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "03fb319d3989c68a39c0652d8ff972e0957c5e6c",
|
||||||
|
"mergedAt": "2020-03-31T20:17:02.000Z",
|
||||||
|
"mergeCommitSha": "5ea204fb61cdb30501f8a6686b7132473f743b69",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"milestone": "0.2.1",
|
||||||
|
"body": "\r\nSigned-off-by: jolheiser <john.olheiser@gmail.com>",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-03-31T20:11:46.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 16,
|
||||||
|
"title": "Add release support and CSV output",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/16",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "5ea204fb61cdb30501f8a6686b7132473f743b69",
|
||||||
|
"mergedAt": "2020-04-17T03:59:15.000Z",
|
||||||
|
"mergeCommitSha": "0a6162ad05900394d381eef9ec05704b3941c5c4",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"feature"
|
||||||
|
],
|
||||||
|
"milestone": "0.3.0",
|
||||||
|
"body": "Resolves #15\r\n\r\nThis PR adds support for listing and creating releases.\r\n\r\nIt also adds a `--csv <file>` flag to issue/PR/release searches, which will instead dump CSV-formatting information to the specified file.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-04-17T03:54:27.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 17,
|
||||||
|
"title": "Imp formatting",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/17",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "0a6162ad05900394d381eef9ec05704b3941c5c4",
|
||||||
|
"mergedAt": "2020-05-07T01:09:33.000Z",
|
||||||
|
"mergeCommitSha": "448e12ce38128909c32f30b29dc560ac44d1d7a5",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"docs"
|
||||||
|
],
|
||||||
|
"milestone": "0.3.0",
|
||||||
|
"body": "This PR is the result of running [imp](https://gitea.com/jolheiser/imp) against the repo.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-05-07T01:07:19.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 19,
|
||||||
|
"title": "Update Gitea SDK and other modules",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/19",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "448e12ce38128909c32f30b29dc560ac44d1d7a5",
|
||||||
|
"mergedAt": "2020-07-15T18:15:49.000Z",
|
||||||
|
"mergeCommitSha": "e4303d76389f45d9d7a5da29b504200038c46eb4",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.3.0",
|
||||||
|
"body": "As title",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-05-28T03:21:56.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 20,
|
||||||
|
"title": "Update modules",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/20",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "e4303d76389f45d9d7a5da29b504200038c46eb4",
|
||||||
|
"mergedAt": "2020-09-13T03:59:45.000Z",
|
||||||
|
"mergeCommitSha": "dac69ffbd020f83a39b8fadcf3dcb928ed0826f1",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"milestone": "0.4.0",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-13T03:36:59.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 21,
|
||||||
|
"title": "Add open functionality",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/21",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "dac69ffbd020f83a39b8fadcf3dcb928ed0826f1",
|
||||||
|
"mergedAt": "2020-09-13T04:34:13.000Z",
|
||||||
|
"mergeCommitSha": "b4d7ff5775e913e3681c6c2f1009e37591a060cf",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"feature"
|
||||||
|
],
|
||||||
|
"milestone": "0.4.0",
|
||||||
|
"body": "Closes #11\n\nThis PR adds functionality to open a repo/issue/PR\n\nTo open the current repo `sip open`\n\nTo open an issue `sip open 1234`\n\nTo open a different repo `sip open jolheiser/vanity`",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-13T04:23:10.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 22,
|
||||||
|
"title": "Add changelog for 0.3.0 and 0.4.0",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/22",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "b4d7ff5775e913e3681c6c2f1009e37591a060cf",
|
||||||
|
"mergedAt": "2020-09-13T04:42:13.000Z",
|
||||||
|
"mergeCommitSha": "40e256e8b9da14692f348ec10db17f773569c66f",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"docs",
|
||||||
|
"skip-changelog"
|
||||||
|
],
|
||||||
|
"milestone": "0.4.0",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-13T04:41:50.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 23,
|
||||||
|
"title": "Update Gitea SDK",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/23",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "40e256e8b9da14692f348ec10db17f773569c66f",
|
||||||
|
"mergedAt": "2020-09-15T18:02:46.000Z",
|
||||||
|
"mergeCommitSha": "8db0c08253f7e30ef86a8ba67169ea4d3e4cf72b",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-15T17:57:59.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 24,
|
||||||
|
"title": "Update repo info",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/24",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "8db0c08253f7e30ef86a8ba67169ea4d3e4cf72b",
|
||||||
|
"mergedAt": "2020-09-16T03:54:50.000Z",
|
||||||
|
"mergeCommitSha": "3e49adf6047960a03f53346bbececb3ce7e0809b",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "Now that the SDK supports forks, watchers, stars, etc.\n\nThis PR updates the `sip repo` information",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-16T03:48:01.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 26,
|
||||||
|
"title": "Add release attachments",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/26",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "3e49adf6047960a03f53346bbececb3ce7e0809b",
|
||||||
|
"mergedAt": "2020-09-16T18:07:32.000Z",
|
||||||
|
"mergeCommitSha": "a51305f8162b0a5ec80387db0b5ecc8a89e209be",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "Resolves #25",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-16T17:57:57.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 29,
|
||||||
|
"title": "Refactor",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/29",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "a51305f8162b0a5ec80387db0b5ecc8a89e209be",
|
||||||
|
"mergedAt": "2020-09-17T16:25:11.000Z",
|
||||||
|
"mergeCommitSha": "894a641ef86c444dccfa55eca457186b5e10da95",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "Fixes #27\n\nFixes #28\n\nThis PR refactors and cleans up packages.\n\nIt also scans CLI flags into variables for fewer footguns.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-17T04:11:50.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 30,
|
||||||
|
"title": "Changelog 0.5.0",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/30",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "894a641ef86c444dccfa55eca457186b5e10da95",
|
||||||
|
"mergedAt": "2020-09-17T16:34:42.000Z",
|
||||||
|
"mergeCommitSha": "cce2360f0fcec4f63c66e5b05bac25a7ba42f942",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"docs"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "## [0.5.0](https://gitea.com/jolheiser/sip/pulls?q=&type=all&state=closed&milestone=1311) - 2020-09-17\r\n\r\n<details><summary>ENHANCEMENTS</summary>\r\n\r\n* Refactor (#29)\r\n* Add release attachments (#26)\r\n* Update repo info (#24)\r\n</details>\r\n<details><summary>BUILD</summary>\r\n\r\n* Update Gitea SDK (#23)\r\n</details>\r\n",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-17T16:34:05.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 36,
|
||||||
|
"title": "Add attachment removal and change message",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/36",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "cce2360f0fcec4f63c66e5b05bac25a7ba42f942",
|
||||||
|
"mergedAt": "2020-09-21T14:19:38.000Z",
|
||||||
|
"mergeCommitSha": "0bbe2e35ff5b482bae10ecf7abcd89815274c217",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.1",
|
||||||
|
"body": "Fixes #35\r\n\r\nChanges the message to instead tell the user how many files were added/removed from the release.\r\n\r\nThis PR also adds a way to multi-select attachments to be removed from a release via `sip release attach remove` since `sip release remove` will be reserved for removing a release in the future.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-21T03:59:49.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 37,
|
||||||
|
"title": "Change to vanity URL",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/37",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "0bbe2e35ff5b482bae10ecf7abcd89815274c217",
|
||||||
|
"mergedAt": "2020-09-21T19:21:09.000Z",
|
||||||
|
"mergeCommitSha": "5ecbcde5180e4a3b12bdc35416c2f050cd0808f1",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"milestone": "",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-21T04:07:33.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"diffInfo": {
|
||||||
|
"changedFiles": 43,
|
||||||
|
"additions": 1942,
|
||||||
|
"deletions": 418,
|
||||||
|
"changes": 0,
|
||||||
|
"commits": 24,
|
||||||
|
"commitInfo": [
|
||||||
|
{
|
||||||
|
"sha": "427ecdb7f1f4e289cb820ce2fbafe158b9b30012",
|
||||||
|
"summary": "Clean up and polish (#1)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-02-18T05:27:52.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-02-18T05:27:52.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "5929bebe01e7b8c7c57b3c8fdfd41d4038bb85a1",
|
||||||
|
"summary": "Add Drone and releases (#2)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-02-18T15:51:10.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-02-18T15:51:10.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "bb773780df3488204df93228bdd72eb59418029b",
|
||||||
|
"summary": "Update Beaver and fix bugs (#6)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-02-27T02:53:11.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-02-27T02:53:11.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "1956062791dae3e66c0c11d6fa86c59b031e51ee",
|
||||||
|
"summary": "Fix PR head nil panic (#7)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-02-27T03:03:32.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-02-27T03:03:32.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "df58f223f25edd30ce8d15328d9d99fc9f98954b",
|
||||||
|
"summary": "Add search filters (#8)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-02-27T04:58:02.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-02-27T04:58:02.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "222dcf402b1cc0b57dbd4e2e9bc34196410c8a6b",
|
||||||
|
"summary": "Changelog 0.2.0 (#9)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-02-27T05:20:29.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-02-27T05:20:29.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "4490cc9888b4e39e14ce1c8fe9bdf64de348de71",
|
||||||
|
"summary": "Add qualifier module (#10)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-03-06T04:18:36.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-03-06T04:18:36.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "03fb319d3989c68a39c0652d8ff972e0957c5e6c",
|
||||||
|
"summary": "Add create repo command (#13)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-03-06T04:21:56.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-03-06T04:21:56.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "64b0335e0ae45a4bd264bbab008551b7820f8811",
|
||||||
|
"summary": "Fix Drone release",
|
||||||
|
"message": "",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"authorDate": "2020-03-31T20:10:18.000Z",
|
||||||
|
"committer": "jolheiser",
|
||||||
|
"commitDate": "2020-03-31T20:10:18.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "5ea204fb61cdb30501f8a6686b7132473f743b69",
|
||||||
|
"summary": "Merge pull request 'Fix Drone release' (#14) from drone-release into master",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-03-31T20:17:01.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-03-31T20:17:01.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "0a6162ad05900394d381eef9ec05704b3941c5c4",
|
||||||
|
"summary": "Add release support and CSV output (#16)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-04-17T03:59:12.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-04-17T03:59:12.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "448e12ce38128909c32f30b29dc560ac44d1d7a5",
|
||||||
|
"summary": "Imp formatting (#17)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-05-07T01:09:31.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-05-07T01:09:31.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "e4303d76389f45d9d7a5da29b504200038c46eb4",
|
||||||
|
"summary": "Update Gitea SDK and other modules (#19)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-07-15T18:15:46.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-07-15T18:15:46.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "dac69ffbd020f83a39b8fadcf3dcb928ed0826f1",
|
||||||
|
"summary": "Update modules (#20)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-13T03:59:43.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-13T03:59:43.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "b4d7ff5775e913e3681c6c2f1009e37591a060cf",
|
||||||
|
"summary": "Add open functionality (#21)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-13T04:34:11.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-13T04:34:11.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "40e256e8b9da14692f348ec10db17f773569c66f",
|
||||||
|
"summary": "Add changelog for 0.3.0 and 0.4.0 (#22)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-13T04:42:11.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-13T04:42:11.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "8db0c08253f7e30ef86a8ba67169ea4d3e4cf72b",
|
||||||
|
"summary": "Update Gitea SDK (#23)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-15T18:02:45.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-15T18:02:45.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "3e49adf6047960a03f53346bbececb3ce7e0809b",
|
||||||
|
"summary": "Update repo info (#24)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-16T03:54:48.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-16T03:54:48.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "a51305f8162b0a5ec80387db0b5ecc8a89e209be",
|
||||||
|
"summary": "Add release attachments (#26)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-16T18:07:30.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-16T18:07:30.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "894a641ef86c444dccfa55eca457186b5e10da95",
|
||||||
|
"summary": "Refactor (#29)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-17T16:25:09.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-17T16:25:09.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "cce2360f0fcec4f63c66e5b05bac25a7ba42f942",
|
||||||
|
"summary": "Changelog 0.5.0 (#30)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-17T16:34:40.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-17T16:34:40.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "0bbe2e35ff5b482bae10ecf7abcd89815274c217",
|
||||||
|
"summary": "Add attachment removal and change message (#36)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-21T14:19:36.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-21T14:19:36.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "5ecbcde5180e4a3b12bdc35416c2f050cd0808f1",
|
||||||
|
"summary": "Change to vanity URL (#37)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-21T19:21:07.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-21T19:21:07.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "1742fcc37c35faca189eae173cd803e9623a8b80",
|
||||||
|
"summary": "Fix drone-gitea-main (#38)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-21T19:30:21.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-21T19:30:21.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"owner": "jolheiser",
|
||||||
|
"repo": "sip",
|
||||||
|
"fromTag": {
|
||||||
|
"name": "v0.1.0"
|
||||||
|
},
|
||||||
|
"toTag": {
|
||||||
|
"name": "master"
|
||||||
|
},
|
||||||
|
"includeOpen": false,
|
||||||
|
"failOnError": false,
|
||||||
|
"fetchViaCommits": false,
|
||||||
|
"fetchReviewers": false,
|
||||||
|
"fetchReleaseInformation": false,
|
||||||
|
"fetchReviews": false,
|
||||||
|
"commitMode": false,
|
||||||
|
"configuration": {
|
||||||
|
"max_tags_to_fetch": 200,
|
||||||
|
"max_pull_requests": 1000,
|
||||||
|
"max_back_track_time_days": 1000,
|
||||||
|
"exclude_merge_branches": [],
|
||||||
|
"sort": "ASC",
|
||||||
|
"template": "#{{CHANGELOG}}",
|
||||||
|
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
|
||||||
|
"empty_template": "- no changes",
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": [
|
||||||
|
"add",
|
||||||
|
"Add"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": [
|
||||||
|
"fix",
|
||||||
|
"Fix"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ignore_labels": [
|
||||||
|
"ignore"
|
||||||
|
],
|
||||||
|
"label_extractor": [
|
||||||
|
{
|
||||||
|
"pattern": "(\\w+) (.+)",
|
||||||
|
"target": "$1",
|
||||||
|
"on_property": "title"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transformers": [],
|
||||||
|
"tag_resolver": {
|
||||||
|
"method": "semver"
|
||||||
|
},
|
||||||
|
"base_branches": [],
|
||||||
|
"custom_placeholders": [],
|
||||||
|
"trim_values": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
{
|
||||||
|
"mergedPullRequests": [
|
||||||
|
{
|
||||||
|
"number": 36,
|
||||||
|
"title": "Add attachment removal and change message",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/36",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "cce2360f0fcec4f63c66e5b05bac25a7ba42f942",
|
||||||
|
"mergedAt": "2020-09-21T14:19:38.000Z",
|
||||||
|
"mergeCommitSha": "0bbe2e35ff5b482bae10ecf7abcd89815274c217",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.1",
|
||||||
|
"body": "Fixes #35\r\n\r\nChanges the message to instead tell the user how many files were added/removed from the release.\r\n\r\nThis PR also adds a way to multi-select attachments to be removed from a release via `sip release attach remove` since `sip release remove` will be reserved for removing a release in the future.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-21T03:59:49.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 37,
|
||||||
|
"title": "Change to vanity URL",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/37",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "0bbe2e35ff5b482bae10ecf7abcd89815274c217",
|
||||||
|
"mergedAt": "2020-09-21T19:21:09.000Z",
|
||||||
|
"mergeCommitSha": "5ecbcde5180e4a3b12bdc35416c2f050cd0808f1",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"milestone": "",
|
||||||
|
"body": "",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-21T04:07:33.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 38,
|
||||||
|
"title": "Fix drone-gitea-main",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/38",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "5ecbcde5180e4a3b12bdc35416c2f050cd0808f1",
|
||||||
|
"mergedAt": "2020-09-21T19:30:23.000Z",
|
||||||
|
"mergeCommitSha": "1742fcc37c35faca189eae173cd803e9623a8b80",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"bug",
|
||||||
|
"build",
|
||||||
|
"skip-changelog"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.1",
|
||||||
|
"body": "No `:1` tag exists for the image, only `latest`.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-21T19:30:06.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"diffInfo": {
|
||||||
|
"changedFiles": 24,
|
||||||
|
"additions": 160,
|
||||||
|
"deletions": 41,
|
||||||
|
"changes": 0,
|
||||||
|
"commits": 3,
|
||||||
|
"commitInfo": [
|
||||||
|
{
|
||||||
|
"sha": "0bbe2e35ff5b482bae10ecf7abcd89815274c217",
|
||||||
|
"summary": "Add attachment removal and change message (#36)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-21T14:19:36.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-21T14:19:36.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "5ecbcde5180e4a3b12bdc35416c2f050cd0808f1",
|
||||||
|
"summary": "Change to vanity URL (#37)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-21T19:21:07.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-21T19:21:07.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "1742fcc37c35faca189eae173cd803e9623a8b80",
|
||||||
|
"summary": "Fix drone-gitea-main (#38)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-21T19:30:21.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-21T19:30:21.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"owner": "jolheiser",
|
||||||
|
"repo": "sip",
|
||||||
|
"fromTag": {
|
||||||
|
"name": "v0.5.0"
|
||||||
|
},
|
||||||
|
"toTag": {
|
||||||
|
"name": "master"
|
||||||
|
},
|
||||||
|
"includeOpen": false,
|
||||||
|
"failOnError": false,
|
||||||
|
"fetchViaCommits": true,
|
||||||
|
"fetchReviewers": false,
|
||||||
|
"fetchReleaseInformation": false,
|
||||||
|
"fetchReviews": false,
|
||||||
|
"commitMode": false,
|
||||||
|
"configuration": {
|
||||||
|
"max_tags_to_fetch": 200,
|
||||||
|
"max_pull_requests": 1000,
|
||||||
|
"max_back_track_time_days": 1000,
|
||||||
|
"exclude_merge_branches": [],
|
||||||
|
"sort": "ASC",
|
||||||
|
"template": "#{{CHANGELOG}}",
|
||||||
|
"pr_template": "- #{{TITLE}}\n - PR: ##{{NUMBER}}",
|
||||||
|
"empty_template": "- no changes",
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": [
|
||||||
|
"add",
|
||||||
|
"Add"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": [
|
||||||
|
"fix",
|
||||||
|
"Fix"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🧪 Upgrade",
|
||||||
|
"labels": [
|
||||||
|
"upgrade",
|
||||||
|
"Upgrade",
|
||||||
|
"Clean"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ignore_labels": [
|
||||||
|
"ignore"
|
||||||
|
],
|
||||||
|
"label_extractor": [
|
||||||
|
{
|
||||||
|
"pattern": "(\\w+) (.+)",
|
||||||
|
"target": "$1",
|
||||||
|
"on_property": "title"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transformers": [],
|
||||||
|
"tag_resolver": {
|
||||||
|
"method": "semver"
|
||||||
|
},
|
||||||
|
"base_branches": [],
|
||||||
|
"custom_placeholders": [],
|
||||||
|
"trim_values": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
{
|
||||||
|
"mergedPullRequests": [
|
||||||
|
{
|
||||||
|
"number": 26,
|
||||||
|
"title": "Add release attachments",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/26",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "3e49adf6047960a03f53346bbececb3ce7e0809b",
|
||||||
|
"mergedAt": "2020-09-16T18:07:32.000Z",
|
||||||
|
"mergeCommitSha": "a51305f8162b0a5ec80387db0b5ecc8a89e209be",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "Resolves #25",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-16T17:57:57.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 29,
|
||||||
|
"title": "Refactor",
|
||||||
|
"htmlURL": "https://gitea.com/jolheiser/sip/pulls/29",
|
||||||
|
"baseBranch": "master",
|
||||||
|
"branch": "a51305f8162b0a5ec80387db0b5ecc8a89e209be",
|
||||||
|
"mergedAt": "2020-09-17T16:25:11.000Z",
|
||||||
|
"mergeCommitSha": "894a641ef86c444dccfa55eca457186b5e10da95",
|
||||||
|
"author": "jolheiser",
|
||||||
|
"repoName": "jolheiser/sip",
|
||||||
|
"labels": [
|
||||||
|
"enhancement"
|
||||||
|
],
|
||||||
|
"milestone": "0.5.0",
|
||||||
|
"body": "Fixes #27\n\nFixes #28\n\nThis PR refactors and cleans up packages.\n\nIt also scans CLI flags into variables for fewer footguns.",
|
||||||
|
"approvedReviewers": [],
|
||||||
|
"createdAt": "2020-09-17T04:11:50.000Z",
|
||||||
|
"status": "merged"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"diffInfo": {
|
||||||
|
"changedFiles": 36,
|
||||||
|
"additions": 576,
|
||||||
|
"deletions": 205,
|
||||||
|
"changes": 0,
|
||||||
|
"commits": 2,
|
||||||
|
"commitInfo": [
|
||||||
|
{
|
||||||
|
"sha": "a51305f8162b0a5ec80387db0b5ecc8a89e209be",
|
||||||
|
"summary": "Add release attachments (#26)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-16T18:07:30.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-16T18:07:30.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sha": "894a641ef86c444dccfa55eca457186b5e10da95",
|
||||||
|
"summary": "Refactor (#29)",
|
||||||
|
"message": "",
|
||||||
|
"author": "John Olheiser",
|
||||||
|
"authorDate": "2020-09-17T16:25:09.000Z",
|
||||||
|
"committer": "John Olheiser",
|
||||||
|
"commitDate": "2020-09-17T16:25:09.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"owner": "jolheiser",
|
||||||
|
"repo": "sip",
|
||||||
|
"fromTag": {
|
||||||
|
"name": "3e49adf6047960a03f53346bbececb3ce7e0809b"
|
||||||
|
},
|
||||||
|
"toTag": {
|
||||||
|
"name": "894a641ef86c444dccfa55eca457186b5e10da95"
|
||||||
|
},
|
||||||
|
"includeOpen": false,
|
||||||
|
"failOnError": false,
|
||||||
|
"fetchViaCommits": true,
|
||||||
|
"fetchReviewers": false,
|
||||||
|
"fetchReleaseInformation": false,
|
||||||
|
"fetchReviews": false,
|
||||||
|
"commitMode": false,
|
||||||
|
"configuration": {
|
||||||
|
"max_tags_to_fetch": 200,
|
||||||
|
"max_pull_requests": 1000,
|
||||||
|
"max_back_track_time_days": 1000,
|
||||||
|
"exclude_merge_branches": [],
|
||||||
|
"sort": {
|
||||||
|
"order": "ASC",
|
||||||
|
"on_property": "mergedAt"
|
||||||
|
},
|
||||||
|
"template": "#{{CHANGELOG}}",
|
||||||
|
"pr_template": "#{{TITLE}}\n#{{NUMBER}}\n#{{URL}}\n#{{MERGED_AT}}\n#{{AUTHOR}}\n#{{LABELS}}\n#{{MILESTONE}}\n#{{BODY}}\n#{{ASSIGNEES}}\n#{{REVIEWERS}}",
|
||||||
|
"empty_template": "- no changes",
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": [
|
||||||
|
"feature"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": [
|
||||||
|
"fix"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🧪 Tests",
|
||||||
|
"labels": [
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 📦 Uncategorized",
|
||||||
|
"labels": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ignore_labels": [
|
||||||
|
"ignore"
|
||||||
|
],
|
||||||
|
"label_extractor": [],
|
||||||
|
"transformers": [],
|
||||||
|
"tag_resolver": {
|
||||||
|
"method": "semver"
|
||||||
|
},
|
||||||
|
"base_branches": [],
|
||||||
|
"custom_placeholders": [],
|
||||||
|
"trim_values": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": ["add","Add"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": ["fix","Fix"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🧪 Upgrade",
|
||||||
|
"labels": ["upgrade","Upgrade","Clean"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"label_extractor": [
|
||||||
|
{
|
||||||
|
"pattern": "(\\w+) (.+)",
|
||||||
|
"target": "$1",
|
||||||
|
"on_property": "title"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort": "ASC",
|
||||||
|
"template": "${{CHANGELOG}}",
|
||||||
|
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
|
||||||
|
"empty_template": "- no changes",
|
||||||
|
"max_pull_requests": 1000,
|
||||||
|
"max_back_track_time_days": 1000
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": ["add","Add"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": ["fix","Fix"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🧪 Upgrade",
|
||||||
|
"labels": ["upgrade","Upgrade","Clean"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"label_extractor": [
|
||||||
|
{
|
||||||
|
"pattern": "(\\w+) (.+)",
|
||||||
|
"target": "$1",
|
||||||
|
"on_property": "title"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort": "DESC",
|
||||||
|
"template": "${{CHANGELOG}}",
|
||||||
|
"pr_template": "- ${{TITLE}}\n - PR: #${{NUMBER}}",
|
||||||
|
"empty_template": "- no changes",
|
||||||
|
"max_pull_requests": 1000,
|
||||||
|
"max_back_track_time_days": 1000
|
||||||
|
}
|
||||||
+6672
-481
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
+25
@@ -553,6 +553,31 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
|||||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
gitea-js
|
||||||
|
MIT
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 Anbraten
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
has-flag
|
has-flag
|
||||||
MIT
|
MIT
|
||||||
MIT License
|
MIT License
|
||||||
|
|||||||
Generated
+413
-216
File diff suppressed because it is too large
Load Diff
+13
-9
@@ -1,17 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "release-changelog-builder-action",
|
"name": "release-changelog-builder-action",
|
||||||
"version": "v4.0.0",
|
"version": "v4.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "A GitHub action that builds your release notes / changelog fast, easy and exactly the way you want.",
|
"description": "A GitHub action that builds your release notes / changelog fast, easy and exactly the way you want.",
|
||||||
"main": "lib/main.js",
|
"main": "lib/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --write **/*.ts **/**/*.ts",
|
||||||
"format-check": "prettier --check **/*.ts",
|
"format-check": "prettier --check **/*.ts",
|
||||||
|
"format-fix": "eslint --fix src/**/*.ts",
|
||||||
"lint": "eslint src/**/*.ts",
|
"lint": "eslint src/**/*.ts",
|
||||||
"package": "ncc build --source-map --license licenses.txt",
|
"package": "ncc build --source-map --license licenses.txt",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"all": "npm run build && npm run format && npm run lint && npm run package && npm test"
|
"test-github": "jest __tests__/*.test.ts",
|
||||||
|
"test-gitea": "jest __tests__/gitea/*.test.ts",
|
||||||
|
"all": "npm run build && npm run format && npm run lint && npm run package && npm run test-github"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -36,20 +39,21 @@
|
|||||||
"@actions/exec": "^1.1.1",
|
"@actions/exec": "^1.1.1",
|
||||||
"@actions/github": "^6.0.0",
|
"@actions/github": "^6.0.0",
|
||||||
"@octokit/rest": "^20.0.2",
|
"@octokit/rest": "^20.0.2",
|
||||||
|
"gitea-js": "^1.20.1",
|
||||||
"https-proxy-agent": "^7.0.2",
|
"https-proxy-agent": "^7.0.2",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"semver": "^7.5.4"
|
"semver": "^7.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.6",
|
"@types/jest": "^29.5.7",
|
||||||
"@types/node": "^20.8.7",
|
"@types/node": "^20.8.10",
|
||||||
"@types/semver": "^7.5.4",
|
"@types/semver": "^7.5.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
||||||
"@typescript-eslint/parser": "^6.8.0",
|
"@typescript-eslint/parser": "^6.9.1",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
"eslint": "^8.51.0",
|
"eslint": "^8.53.0",
|
||||||
"eslint-plugin-github": "^4.10.1",
|
"eslint-plugin-github": "^4.10.1",
|
||||||
"eslint-plugin-jest": "^27.4.2",
|
"eslint-plugin-jest": "^27.6.0",
|
||||||
"eslint-plugin-prettier": "^5.0.1",
|
"eslint-plugin-prettier": "^5.0.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-circus": "^29.7.0",
|
"jest-circus": "^29.7.0",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Rule, Extractor, Regex, Transformer, Sort, PullConfiguration} from './pr-collector/types'
|
import {Extractor, PullConfiguration, Regex, Rule, Sort, Transformer} from './pr-collector/types'
|
||||||
|
|
||||||
export interface Configuration extends PullConfiguration {
|
export interface Configuration extends PullConfiguration {
|
||||||
max_tags_to_fetch: number
|
max_tags_to_fetch: number
|
||||||
|
|||||||
+20
-3
@@ -3,13 +3,29 @@ import * as github from '@actions/github'
|
|||||||
import {mergeConfiguration, parseConfiguration, resolveConfiguration, retrieveRepositoryPath, writeOutput} from './utils'
|
import {mergeConfiguration, parseConfiguration, resolveConfiguration, retrieveRepositoryPath, writeOutput} from './utils'
|
||||||
import {ReleaseNotesBuilder} from './releaseNotesBuilder'
|
import {ReleaseNotesBuilder} from './releaseNotesBuilder'
|
||||||
import {Configuration} from './configuration'
|
import {Configuration} from './configuration'
|
||||||
|
import {GithubRepository} from './repositories/GithubRepository'
|
||||||
|
import {GiteaRepository} from './repositories/GiteaRepository'
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
core.setOutput('failed', false) // mark the action not failed by default
|
const supportedPlatform = {
|
||||||
|
github: GithubRepository,
|
||||||
|
gitea: GiteaRepository
|
||||||
|
}
|
||||||
|
function isSupportedPlatform(type: string): type is keyof typeof supportedPlatform {
|
||||||
|
return type in supportedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
core.setOutput('failed', false) // mark the action not failed by default
|
||||||
core.startGroup(`📘 Reading input values`)
|
core.startGroup(`📘 Reading input values`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// read in path specification, resolve github workspace, and repo path
|
// read in path specification, resolve github workspace, and repo path
|
||||||
|
const platform = core.getInput('platform') || 'github'
|
||||||
|
if (!isSupportedPlatform(platform)) {
|
||||||
|
core.setFailed(`The ${platform} platform is not supported. `)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const inputPath = core.getInput('path')
|
const inputPath = core.getInput('path')
|
||||||
const repositoryPath = retrieveRepositoryPath(inputPath)
|
const repositoryPath = retrieveRepositoryPath(inputPath)
|
||||||
|
|
||||||
@@ -40,7 +56,7 @@ async function run(): Promise<void> {
|
|||||||
|
|
||||||
// read in repository inputs
|
// read in repository inputs
|
||||||
const baseUrl = core.getInput('baseUrl')
|
const baseUrl = core.getInput('baseUrl')
|
||||||
const token = core.getInput('token')
|
const token = core.getInput('token') || process.env.GITHUB_TOKEN || ''
|
||||||
const owner = core.getInput('owner') || github.context.repo.owner
|
const owner = core.getInput('owner') || github.context.repo.owner
|
||||||
const repo = core.getInput('repo') || github.context.repo.repo
|
const repo = core.getInput('repo') || github.context.repo.repo
|
||||||
// read in from, to tag inputs
|
// read in from, to tag inputs
|
||||||
@@ -59,9 +75,10 @@ async function run(): Promise<void> {
|
|||||||
const exportOnly = core.getInput('exportOnly') === 'true'
|
const exportOnly = core.getInput('exportOnly') === 'true'
|
||||||
const cache = core.getInput('cache')
|
const cache = core.getInput('cache')
|
||||||
|
|
||||||
|
const repositoryUtils = new supportedPlatform[platform](token, baseUrl, repositoryPath)
|
||||||
const result = await new ReleaseNotesBuilder(
|
const result = await new ReleaseNotesBuilder(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
token,
|
repositoryUtils,
|
||||||
repositoryPath,
|
repositoryPath,
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../pr-collector/src/
|
|
||||||
Executable → Regular
+4
-59
@@ -1,9 +1,9 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Octokit, RestEndpointMethodTypes} from '@octokit/rest'
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import {failOrError} from './utils'
|
import {failOrError} from './utils'
|
||||||
import {PullRequestInfo} from './pullRequests'
|
import {PullRequestInfo} from './pullRequests'
|
||||||
import {Options} from './prCollector'
|
import {Options} from './prCollector'
|
||||||
|
import {BaseRepository} from '../repositories/BaseRepository'
|
||||||
|
|
||||||
export interface DiffInfo {
|
export interface DiffInfo {
|
||||||
changedFiles: number
|
changedFiles: number
|
||||||
@@ -34,7 +34,7 @@ export interface CommitInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Commits {
|
export class Commits {
|
||||||
constructor(private octokit: Octokit) {}
|
constructor(private repositoryUtils: BaseRepository) {}
|
||||||
|
|
||||||
async getDiff(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
async getDiff(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
const diff: DiffInfo = await this.getDiffRemote(owner, repo, base, head)
|
const diff: DiffInfo = await this.getDiffRemote(owner, repo, base, head)
|
||||||
@@ -43,62 +43,7 @@ export class Commits {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
private async getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
let changedFilesCount = 0
|
return this.repositoryUtils.getDiffRemote(owner, repo, base, head)
|
||||||
let additionCount = 0
|
|
||||||
let deletionCount = 0
|
|
||||||
let changeCount = 0
|
|
||||||
let commitCount = 0
|
|
||||||
|
|
||||||
// Fetch comparisons recursively until we don't find any commits
|
|
||||||
// This is because the GitHub API limits the number of commits returned in a single response.
|
|
||||||
let commits: RestEndpointMethodTypes['repos']['compareCommits']['response']['data']['commits'] = []
|
|
||||||
let compareHead = head
|
|
||||||
// eslint-disable-next-line no-constant-condition
|
|
||||||
while (true) {
|
|
||||||
const compareResult = await this.octokit.repos.compareCommits({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
base,
|
|
||||||
head: compareHead
|
|
||||||
})
|
|
||||||
if (compareResult.data.total_commits === 0) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
changedFilesCount += compareResult.data.files?.length ?? 0
|
|
||||||
const files = compareResult.data.files
|
|
||||||
if (files !== undefined) {
|
|
||||||
for (const file of files) {
|
|
||||||
additionCount += file.additions
|
|
||||||
deletionCount += file.deletions
|
|
||||||
changeCount += file.changes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
commitCount += compareResult.data.commits.length
|
|
||||||
commits = compareResult.data.commits.concat(commits)
|
|
||||||
compareHead = `${commits[0].sha}^`
|
|
||||||
}
|
|
||||||
|
|
||||||
core.info(`ℹ️ Found ${commits.length} commits from the GitHub API for ${owner}/${repo}`)
|
|
||||||
|
|
||||||
return {
|
|
||||||
changedFiles: changedFilesCount,
|
|
||||||
additions: additionCount,
|
|
||||||
deletions: deletionCount,
|
|
||||||
changes: changeCount,
|
|
||||||
commits: commitCount,
|
|
||||||
commitInfo: commits
|
|
||||||
.filter(commit => commit.sha)
|
|
||||||
.map(commit => ({
|
|
||||||
sha: commit.sha || '',
|
|
||||||
summary: commit.commit.message.split('\n')[0],
|
|
||||||
message: commit.commit.message,
|
|
||||||
author: commit.author?.login || '',
|
|
||||||
authorDate: moment(commit.commit.author?.date),
|
|
||||||
committer: commit.committer?.login || '',
|
|
||||||
commitDate: moment(commit.commit.committer?.date),
|
|
||||||
prNumber: undefined
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private sortCommits(commits: CommitInfo[]): CommitInfo[] {
|
private sortCommits(commits: CommitInfo[]): CommitInfo[] {
|
||||||
@@ -129,7 +74,7 @@ export class Commits {
|
|||||||
const {owner, repo, fromTag, toTag, failOnError} = options
|
const {owner, repo, fromTag, toTag, failOnError} = options
|
||||||
core.info(`ℹ️ Comparing ${owner}/${repo} - '${fromTag.name}...${toTag.name}'`)
|
core.info(`ℹ️ Comparing ${owner}/${repo} - '${fromTag.name}...${toTag.name}'`)
|
||||||
|
|
||||||
const commitsApi = new Commits(this.octokit)
|
const commitsApi = new Commits(this.repositoryUtils)
|
||||||
let diffInfo: DiffInfo
|
let diffInfo: DiffInfo
|
||||||
try {
|
try {
|
||||||
diffInfo = await commitsApi.getDiff(owner, repo, fromTag.name, toTag.name)
|
diffInfo = await commitsApi.getDiff(owner, repo, fromTag.name, toTag.name)
|
||||||
@@ -39,7 +39,7 @@ class GitCommandManager {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private async execGit(args: string[], allowAllExitCodes = false, silent = false): Promise<GitOutput> {
|
async execGit(args: string[], allowAllExitCodes = false, silent = false): Promise<GitOutput> {
|
||||||
directoryExistsSync(this.workingDirectory, true)
|
directoryExistsSync(this.workingDirectory, true)
|
||||||
|
|
||||||
const result = new GitOutput()
|
const result = new GitOutput()
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {PullConfiguration} from './types'
|
import {PullConfiguration} from './types'
|
||||||
import {Octokit} from '@octokit/rest'
|
|
||||||
import {TagInfo, Tags} from './tags'
|
import {TagInfo, Tags} from './tags'
|
||||||
import {failOrError} from './utils'
|
import {failOrError} from './utils'
|
||||||
import {HttpsProxyAgent} from 'https-proxy-agent'
|
|
||||||
import {PullRequestInfo, PullRequests} from './pullRequests'
|
import {PullRequestInfo, PullRequests} from './pullRequests'
|
||||||
import {Commits, DiffInfo} from './commits'
|
import {Commits, DiffInfo} from './commits'
|
||||||
|
import {BaseRepository} from '../repositories/BaseRepository'
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
owner: string // the owner of the repository
|
owner: string // the owner of the repository
|
||||||
@@ -32,7 +31,7 @@ export interface Data {
|
|||||||
export class PullRequestCollector {
|
export class PullRequestCollector {
|
||||||
constructor(
|
constructor(
|
||||||
private baseUrl: string | null,
|
private baseUrl: string | null,
|
||||||
private token: string | null,
|
private repositoryUtils: BaseRepository,
|
||||||
private repositoryPath: string,
|
private repositoryPath: string,
|
||||||
private owner: string,
|
private owner: string,
|
||||||
private repo: string,
|
private repo: string,
|
||||||
@@ -51,32 +50,10 @@ export class PullRequestCollector {
|
|||||||
|
|
||||||
async build(): Promise<Data | null> {
|
async build(): Promise<Data | null> {
|
||||||
// check proxy setup for GHES environments
|
// check proxy setup for GHES environments
|
||||||
const proxy = process.env.https_proxy || process.env.HTTPS_PROXY
|
|
||||||
const noProxy = process.env.no_proxy || process.env.NO_PROXY
|
|
||||||
let noProxyArray: string[] = []
|
|
||||||
if (noProxy) {
|
|
||||||
noProxyArray = noProxy.split(',')
|
|
||||||
}
|
|
||||||
|
|
||||||
// load octokit instance
|
|
||||||
const octokit = new Octokit({
|
|
||||||
auth: `token ${this.token || process.env.GITHUB_TOKEN}`,
|
|
||||||
baseUrl: `${this.baseUrl || 'https://api.github.com'}`
|
|
||||||
})
|
|
||||||
|
|
||||||
if (proxy) {
|
|
||||||
const agent = new HttpsProxyAgent(proxy)
|
|
||||||
octokit.hook.before('request', options => {
|
|
||||||
if (noProxyArray.includes(options.request.hostname)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
options.request.agent = agent
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure proper from <-> to tag range
|
// ensure proper from <-> to tag range
|
||||||
core.startGroup(`🔖 Resolve tags`)
|
core.startGroup(`🔖 Resolve tags`)
|
||||||
const tagsApi = new Tags(octokit)
|
const tagsApi = new Tags(this.repositoryUtils)
|
||||||
const tagRange = await tagsApi.retrieveRange(
|
const tagRange = await tagsApi.retrieveRange(
|
||||||
this.repositoryPath,
|
this.repositoryPath,
|
||||||
this.owner,
|
this.owner,
|
||||||
@@ -114,7 +91,7 @@ export class PullRequestCollector {
|
|||||||
|
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
|
|
||||||
return await pullData(octokit, {
|
return await pullData(this.repositoryUtils, {
|
||||||
owner: this.owner,
|
owner: this.owner,
|
||||||
repo: this.repo,
|
repo: this.repo,
|
||||||
fromTag: previousTag,
|
fromTag: previousTag,
|
||||||
@@ -131,14 +108,14 @@ export class PullRequestCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function pullData(octokit: Octokit, options: Options): Promise<Data | null> {
|
export async function pullData(repositoryUtils: BaseRepository, options: Options): Promise<Data | null> {
|
||||||
let mergedPullRequests: PullRequestInfo[]
|
let mergedPullRequests: PullRequestInfo[]
|
||||||
let diffInfo: DiffInfo
|
let diffInfo: DiffInfo
|
||||||
|
|
||||||
const commitsApi = new Commits(octokit)
|
const commitsApi = new Commits(repositoryUtils)
|
||||||
if (!options.commitMode) {
|
if (!options.commitMode) {
|
||||||
core.startGroup(`🚀 Load pull requests`)
|
core.startGroup(`🚀 Load pull requests`)
|
||||||
const pullRequestsApi = new PullRequests(octokit, commitsApi)
|
const pullRequestsApi = new PullRequests(repositoryUtils, commitsApi)
|
||||||
const [info, prs] = await pullRequestsApi.getMergedPullRequests(options)
|
const [info, prs] = await pullRequestsApi.getMergedPullRequests(options)
|
||||||
mergedPullRequests = prs
|
mergedPullRequests = prs
|
||||||
diffInfo = info
|
diffInfo = info
|
||||||
Executable → Regular
+10
-164
@@ -1,10 +1,10 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Octokit, RestEndpointMethodTypes} from '@octokit/rest'
|
import {RestEndpointMethodTypes} from '@octokit/rest'
|
||||||
import {Unpacked} from './utils'
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import {Property, Sort} from './types'
|
import {Property, Sort} from './types'
|
||||||
import {Commits, DiffInfo, filterCommits} from './commits'
|
import {Commits, DiffInfo, filterCommits} from './commits'
|
||||||
import {Options} from './prCollector'
|
import {Options} from './prCollector'
|
||||||
|
import {BaseRepository} from '../repositories/BaseRepository'
|
||||||
|
|
||||||
export interface PullRequestInfo {
|
export interface PullRequestInfo {
|
||||||
number: number
|
number: number
|
||||||
@@ -64,53 +64,20 @@ export const EMPTY_COMMENT_INFO: CommentInfo = {
|
|||||||
state: undefined
|
state: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
type PullData = RestEndpointMethodTypes['pulls']['get']['response']['data']
|
export type PullData = RestEndpointMethodTypes['pulls']['get']['response']['data']
|
||||||
|
|
||||||
type PullsListData = RestEndpointMethodTypes['pulls']['list']['response']['data']
|
export type PullsListData = RestEndpointMethodTypes['pulls']['list']['response']['data']
|
||||||
|
|
||||||
type PullReviewsData = RestEndpointMethodTypes['pulls']['listReviews']['response']['data']
|
export type PullReviewsData = RestEndpointMethodTypes['pulls']['listReviews']['response']['data']
|
||||||
|
|
||||||
export class PullRequests {
|
export class PullRequests {
|
||||||
constructor(
|
constructor(
|
||||||
private octokit: Octokit,
|
private repositoryUtils: BaseRepository,
|
||||||
private commits: Commits
|
private commits: Commits
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async getSingle(owner: string, repo: string, prNumber: number): Promise<PullRequestInfo | null> {
|
|
||||||
try {
|
|
||||||
const {data} = await this.octokit.pulls.get({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
pull_number: prNumber
|
|
||||||
})
|
|
||||||
|
|
||||||
return mapPullRequest(data)
|
|
||||||
} catch (e: any /* eslint-disable-line @typescript-eslint/no-explicit-any */) {
|
|
||||||
core.warning(`⚠️ Cannot find PR ${owner}/${repo}#${prNumber} - ${e.message}`)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getForCommitHash(owner: string, repo: string, commit_sha: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
async getForCommitHash(owner: string, repo: string, commit_sha: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
const mergedPRs: PullRequestInfo[] = []
|
return sortPrs(await this.repositoryUtils.getForCommitHash(owner, repo, commit_sha, maxPullRequests))
|
||||||
|
|
||||||
const options = this.octokit.repos.listPullRequestsAssociatedWithCommit.endpoint.merge({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
commit_sha,
|
|
||||||
per_page: `${Math.min(10, maxPullRequests)}`,
|
|
||||||
direction: 'desc'
|
|
||||||
})
|
|
||||||
|
|
||||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
|
||||||
const prs: PullsListData = response.data as PullsListData
|
|
||||||
|
|
||||||
for (const pr of prs) {
|
|
||||||
mergedPRs.push(mapPullRequest(pr, pr.merged_at ? 'merged' : 'open'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortPrs(mergedPRs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBetweenDates(
|
async getBetweenDates(
|
||||||
@@ -120,86 +87,15 @@ export class PullRequests {
|
|||||||
toDate: moment.Moment,
|
toDate: moment.Moment,
|
||||||
maxPullRequests: number
|
maxPullRequests: number
|
||||||
): Promise<PullRequestInfo[]> {
|
): Promise<PullRequestInfo[]> {
|
||||||
const mergedPRs: PullRequestInfo[] = []
|
return sortPrs(await this.repositoryUtils.getBetweenDates(owner, repo, fromDate, toDate, maxPullRequests))
|
||||||
const options = this.octokit.pulls.list.endpoint.merge({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
state: 'closed',
|
|
||||||
sort: 'merged',
|
|
||||||
per_page: `${Math.min(100, maxPullRequests)}`,
|
|
||||||
direction: 'desc'
|
|
||||||
})
|
|
||||||
|
|
||||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
|
||||||
const prs: PullsListData = response.data as PullsListData
|
|
||||||
|
|
||||||
for (const pr of prs.filter(p => !!p.merged_at)) {
|
|
||||||
mergedPRs.push(mapPullRequest(pr, 'merged'))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mergedPRs.length >= maxPullRequests) {
|
|
||||||
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests} (1)`)
|
|
||||||
break // bail out early to not keep iterating forever
|
|
||||||
} else if (prs.length > 0) {
|
|
||||||
if (fetchedEnough(prs, fromDate)) {
|
|
||||||
return sortPrs(mergedPRs) // bail out early to not keep iterating on PRs super old
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
core.debug(`⚠️ No more PRs retrieved from API. Fetched so far: ${mergedPRs.length}`)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortPrs(mergedPRs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
const openPrs: PullRequestInfo[] = []
|
return sortPrs(await this.repositoryUtils.getOpen(owner, repo, maxPullRequests))
|
||||||
const options = this.octokit.pulls.list.endpoint.merge({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
state: 'open',
|
|
||||||
sort: 'created',
|
|
||||||
per_page: '100',
|
|
||||||
direction: 'desc'
|
|
||||||
})
|
|
||||||
|
|
||||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
|
||||||
const prs: PullsListData = response.data as PullsListData
|
|
||||||
|
|
||||||
for (const pr of prs) {
|
|
||||||
openPrs.push(mapPullRequest(pr, 'open'))
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstPR = prs[0]
|
|
||||||
if (firstPR === undefined || openPrs.length >= maxPullRequests) {
|
|
||||||
if (openPrs.length >= maxPullRequests) {
|
|
||||||
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests} (2)`)
|
|
||||||
}
|
|
||||||
break // bail out early to not keep iterating forever
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sortPrs(openPrs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void> {
|
async getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void> {
|
||||||
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
await this.repositoryUtils.getReviews(owner, repo, pr)
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
pull_number: pr.number,
|
|
||||||
sort: 'created',
|
|
||||||
direction: 'desc'
|
|
||||||
})
|
|
||||||
const prReviews: CommentInfo[] = []
|
|
||||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
|
||||||
const comments: PullReviewsData = response.data as PullReviewsData
|
|
||||||
|
|
||||||
for (const comment of comments) {
|
|
||||||
prReviews.push(mapComment(comment))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pr.reviews = prReviews
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMergedPullRequests(options: Options): Promise<[DiffInfo, PullRequestInfo[]]> {
|
async getMergedPullRequests(options: Options): Promise<[DiffInfo, PullRequestInfo[]]> {
|
||||||
@@ -323,20 +219,6 @@ export class PullRequests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchedEnough(pullRequests: PullsListData, fromDate: moment.Moment): boolean {
|
|
||||||
for (let i = 0; i < Math.min(pullRequests.length, 3); i++) {
|
|
||||||
const firstPR = pullRequests[i]
|
|
||||||
if (!firstPR.merged_at) {
|
|
||||||
continue // no merged_at timestamp -> look for the next
|
|
||||||
} else if (fromDate.isAfter(moment(firstPR.merged_at))) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
break // not enough PRs yet, go further
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function sortPrs(pullRequests: PullRequestInfo[]): PullRequestInfo[] {
|
function sortPrs(pullRequests: PullRequestInfo[]): PullRequestInfo[] {
|
||||||
return sortPullRequests(pullRequests, {
|
return sortPullRequests(pullRequests, {
|
||||||
order: 'ASC',
|
order: 'ASC',
|
||||||
@@ -401,39 +283,3 @@ export function retrieveProperty(pr: PullRequestInfo, property: Property, useCas
|
|||||||
}
|
}
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper function to add a special open label to prs not merged.
|
|
||||||
function attachSpeciaLabels(status: 'open' | 'merged', labels: string[]): string[] {
|
|
||||||
labels.push(`--rcba-${status}`)
|
|
||||||
return labels
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapPullRequest = (pr: PullData | Unpacked<PullsListData>, status: 'open' | 'merged' = 'open'): PullRequestInfo => ({
|
|
||||||
number: pr.number,
|
|
||||||
title: pr.title,
|
|
||||||
htmlURL: pr.html_url,
|
|
||||||
baseBranch: pr.base.ref,
|
|
||||||
branch: pr.head.ref,
|
|
||||||
createdAt: moment(pr.created_at),
|
|
||||||
mergedAt: pr.merged_at ? moment(pr.merged_at) : undefined,
|
|
||||||
mergeCommitSha: pr.merge_commit_sha || '',
|
|
||||||
author: pr.user?.login || '',
|
|
||||||
repoName: pr.base.repo.full_name,
|
|
||||||
labels: attachSpeciaLabels(status, pr.labels?.map(lbl => lbl.name?.toLocaleLowerCase('en') || '') || []),
|
|
||||||
milestone: pr.milestone?.title || '',
|
|
||||||
body: pr.body || '',
|
|
||||||
assignees: pr.assignees?.map(asignee => asignee?.login || '') || [],
|
|
||||||
requestedReviewers: pr.requested_reviewers?.map(reviewer => reviewer?.login || '') || [],
|
|
||||||
approvedReviewers: [],
|
|
||||||
reviews: undefined,
|
|
||||||
status
|
|
||||||
})
|
|
||||||
|
|
||||||
const mapComment = (comment: Unpacked<PullReviewsData>): CommentInfo => ({
|
|
||||||
id: comment.id,
|
|
||||||
htmlURL: comment.html_url,
|
|
||||||
submittedAt: comment.submitted_at ? moment(comment.submitted_at) : undefined,
|
|
||||||
author: comment.user?.login || '',
|
|
||||||
body: comment.body,
|
|
||||||
state: comment.state
|
|
||||||
})
|
|
||||||
Executable → Regular
+4
-59
@@ -1,12 +1,12 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import * as github from '@actions/github'
|
import * as github from '@actions/github'
|
||||||
import * as semver from 'semver'
|
import * as semver from 'semver'
|
||||||
import {Octokit, RestEndpointMethodTypes} from '@octokit/rest'
|
|
||||||
import {SemVer} from 'semver'
|
import {SemVer} from 'semver'
|
||||||
import {RegexTransformer, TagResolver, Transformer} from './types'
|
import {RegexTransformer, TagResolver, Transformer} from './types'
|
||||||
import {createCommandManager} from './gitHelper'
|
import {createCommandManager} from './gitHelper'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import {validateTransformer} from './regexUtils'
|
import {validateTransformer} from './regexUtils'
|
||||||
|
import {BaseRepository} from '../repositories/BaseRepository'
|
||||||
|
|
||||||
export interface TagResult {
|
export interface TagResult {
|
||||||
from: TagInfo | null
|
from: TagInfo | null
|
||||||
@@ -25,69 +25,14 @@ export interface SortableTagInfo extends TagInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Tags {
|
export class Tags {
|
||||||
constructor(private octokit: Octokit) {}
|
constructor(private repositoryUtils: BaseRepository) {}
|
||||||
|
|
||||||
async getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]> {
|
async getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]> {
|
||||||
const tagsInfo: TagInfo[] = []
|
return this.repositoryUtils.getTags(owner, repo, maxTagsToFetch)
|
||||||
const options = this.octokit.repos.listTags.endpoint.merge({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
direction: 'desc',
|
|
||||||
per_page: 100
|
|
||||||
})
|
|
||||||
|
|
||||||
for await (const response of this.octokit.paginate.iterator(options)) {
|
|
||||||
type TagsListData = RestEndpointMethodTypes['repos']['listTags']['response']['data']
|
|
||||||
const tags: TagsListData = response.data as TagsListData
|
|
||||||
|
|
||||||
for (const tag of tags) {
|
|
||||||
tagsInfo.push({
|
|
||||||
name: tag.name,
|
|
||||||
commit: tag.commit.sha
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// for performance only fetch newest maxTagsToFetch tags!!
|
|
||||||
if (tagsInfo.length >= maxTagsToFetch) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
core.info(`ℹ️ Found ${tagsInfo.length} (fetching max: ${maxTagsToFetch}) tags from the GitHub API for ${owner}/${repo}`)
|
|
||||||
return tagsInfo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo> {
|
async fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo> {
|
||||||
const options = this.octokit.repos.getReleaseByTag.endpoint.merge({
|
return this.repositoryUtils.fillTagInformation(repositoryPath, owner, repo, tagInfo)
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
tag: tagInfo.name
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await this.octokit.request(options)
|
|
||||||
type ReleaseInformation = RestEndpointMethodTypes['repos']['getReleaseByTag']['response']['data']
|
|
||||||
|
|
||||||
const release: ReleaseInformation = response.data as ReleaseInformation
|
|
||||||
tagInfo.date = moment(release.created_at)
|
|
||||||
core.info(`ℹ️ Retrieved information about the release associated with ${tagInfo.name} from the GitHub API`)
|
|
||||||
} catch (error) {
|
|
||||||
core.info(`⚠️ No release information found for ${tagInfo.name}, trying to retrieve tag creation time as fallback.`)
|
|
||||||
const gitHelper = await createCommandManager(repositoryPath)
|
|
||||||
const creationTimeString = await gitHelper.tagCreation(tagInfo.name)
|
|
||||||
const creationTime = moment(creationTimeString)
|
|
||||||
if (creationTimeString !== null && creationTime.isValid()) {
|
|
||||||
tagInfo.date = creationTime
|
|
||||||
core.info(
|
|
||||||
`ℹ️ Resolved tag creation time (${creationTimeString}) from 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}`
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
core.info(
|
|
||||||
`⚠️ Could not retrieve tag creation time via git cli 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}'`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tagInfo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async findPredecessorTag(
|
async findPredecessorTag(
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Rule, RegexTransformer} from './pr-collector/types'
|
import {RegexTransformer, Rule} from './pr-collector/types'
|
||||||
import {PullRequestInfo, retrieveProperty} from './pr-collector/pullRequests'
|
import {PullRequestInfo, retrieveProperty} from './pr-collector/pullRequests'
|
||||||
import {validateTransformer} from './pr-collector/regexUtils'
|
import {validateTransformer} from './pr-collector/regexUtils'
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
import {Configuration} from './configuration'
|
import {Configuration} from './configuration'
|
||||||
import {checkExportedData, writeCacheData} from './utils'
|
import {checkExportedData, writeCacheData} from './utils'
|
||||||
import {PullRequestData, buildChangelog} from './transform'
|
import {buildChangelog, PullRequestData} from './transform'
|
||||||
import {PullRequestCollector} from './pr-collector/prCollector'
|
import {PullRequestCollector} from './pr-collector/prCollector'
|
||||||
import {failOrError} from './pr-collector/utils'
|
import {failOrError} from './pr-collector/utils'
|
||||||
import {TagInfo} from './pr-collector/tags'
|
import {TagInfo} from './pr-collector/tags'
|
||||||
import {DiffInfo} from './pr-collector/commits'
|
import {DiffInfo} from './pr-collector/commits'
|
||||||
import {PullRequestInfo} from './pr-collector/pullRequests'
|
import {PullRequestInfo} from './pr-collector/pullRequests'
|
||||||
import * as fs from 'fs'
|
import {BaseRepository} from './repositories/BaseRepository'
|
||||||
|
|
||||||
export interface ReleaseNotesOptions {
|
export interface ReleaseNotesOptions {
|
||||||
owner: string // the owner of the repository
|
owner: string // the owner of the repository
|
||||||
@@ -21,6 +21,7 @@ export interface ReleaseNotesOptions {
|
|||||||
fetchReviews: boolean // defines if the action should fetch the reviews for the PR.
|
fetchReviews: boolean // defines if the action should fetch the reviews for the PR.
|
||||||
commitMode: boolean // defines if we use the alternative commit based mode. note: this is only partially supported
|
commitMode: boolean // defines if we use the alternative commit based mode. note: this is only partially supported
|
||||||
configuration: Configuration // the configuration as defined in `configuration.ts`
|
configuration: Configuration // the configuration as defined in `configuration.ts`
|
||||||
|
repositoryUtils: BaseRepository // the repository implementation used to generate the changelog
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Data {
|
export interface Data {
|
||||||
@@ -32,7 +33,7 @@ export interface Data {
|
|||||||
export class ReleaseNotesBuilder {
|
export class ReleaseNotesBuilder {
|
||||||
constructor(
|
constructor(
|
||||||
private baseUrl: string | null,
|
private baseUrl: string | null,
|
||||||
private token: string | null,
|
private repositoryUtils: BaseRepository,
|
||||||
private repositoryPath: string,
|
private repositoryPath: string,
|
||||||
private owner: string | null,
|
private owner: string | null,
|
||||||
private repo: string | null,
|
private repo: string | null,
|
||||||
@@ -78,7 +79,7 @@ export class ReleaseNotesBuilder {
|
|||||||
|
|
||||||
const prData = await new PullRequestCollector(
|
const prData = await new PullRequestCollector(
|
||||||
this.baseUrl,
|
this.baseUrl,
|
||||||
this.token,
|
this.repositoryUtils,
|
||||||
this.repositoryPath,
|
this.repositoryPath,
|
||||||
this.owner,
|
this.owner,
|
||||||
this.repo,
|
this.repo,
|
||||||
@@ -110,7 +111,8 @@ export class ReleaseNotesBuilder {
|
|||||||
fetchReleaseInformation: this.fetchReleaseInformation,
|
fetchReleaseInformation: this.fetchReleaseInformation,
|
||||||
fetchReviews: this.fetchReviews,
|
fetchReviews: this.fetchReviews,
|
||||||
commitMode: this.commitMode,
|
commitMode: this.commitMode,
|
||||||
configuration: this.configuration
|
configuration: this.configuration,
|
||||||
|
repositoryUtils: this.repositoryUtils
|
||||||
}
|
}
|
||||||
const mergedPullRequests = prData.mergedPullRequests
|
const mergedPullRequests = prData.mergedPullRequests
|
||||||
const diffInfo = prData.diffInfo
|
const diffInfo = prData.diffInfo
|
||||||
@@ -163,7 +165,8 @@ export class ReleaseNotesBuilder {
|
|||||||
fetchReleaseInformation: this.fetchReleaseInformation || orgOptions.fetchReleaseInformation,
|
fetchReleaseInformation: this.fetchReleaseInformation || orgOptions.fetchReleaseInformation,
|
||||||
fetchReviews: this.fetchReviews || orgOptions.fetchReviews,
|
fetchReviews: this.fetchReviews || orgOptions.fetchReviews,
|
||||||
commitMode: this.commitMode || orgOptions.commitMode,
|
commitMode: this.commitMode || orgOptions.commitMode,
|
||||||
configuration: this.configuration || orgOptions.configuration
|
configuration: this.configuration || orgOptions.configuration,
|
||||||
|
repositoryUtils: this.repositoryUtils || orgOptions.repositoryUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setOutputs(options, diffInfo, mergedPullRequests)
|
this.setOutputs(options, diffInfo, mergedPullRequests)
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import {TagInfo} from '../pr-collector/tags'
|
||||||
|
import {DiffInfo} from '../pr-collector/commits'
|
||||||
|
import moment from 'moment/moment'
|
||||||
|
import {PullRequestInfo} from '../pr-collector/pullRequests'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import {createCommandManager} from '../pr-collector/gitHelper'
|
||||||
|
|
||||||
|
export abstract class BaseRepository {
|
||||||
|
proxy?: string
|
||||||
|
noProxyArray: string[]
|
||||||
|
|
||||||
|
// Define an abstract getter for the default URL
|
||||||
|
abstract get defaultUrl(): string
|
||||||
|
|
||||||
|
// Define the abstract getter for the home URL (also used for some replace patterns)
|
||||||
|
abstract get homeUrl(): string
|
||||||
|
|
||||||
|
protected constructor(
|
||||||
|
protected token: string,
|
||||||
|
protected url: string | undefined,
|
||||||
|
protected repositoryPath: string
|
||||||
|
) {
|
||||||
|
this.proxy = process.env.https_proxy || process.env.HTTPS_PROXY
|
||||||
|
const noProxy = process.env.no_proxy || process.env.NO_PROXY
|
||||||
|
this.noProxyArray = []
|
||||||
|
if (noProxy) {
|
||||||
|
this.noProxyArray = noProxy.split(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]>
|
||||||
|
|
||||||
|
abstract fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo>
|
||||||
|
|
||||||
|
abstract getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo>
|
||||||
|
|
||||||
|
abstract getForCommitHash(owner: string, repo: string, commit_sha: string, maxPullRequests: number): Promise<PullRequestInfo[]>
|
||||||
|
|
||||||
|
abstract getBetweenDates(
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
fromDate: moment.Moment,
|
||||||
|
toDate: moment.Moment,
|
||||||
|
maxPullRequests: number
|
||||||
|
): Promise<PullRequestInfo[]>
|
||||||
|
|
||||||
|
abstract getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]>
|
||||||
|
|
||||||
|
abstract getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void>
|
||||||
|
|
||||||
|
protected async getTagByCreateTime(repositoryPath: string, tagInfo: TagInfo): Promise<TagInfo> {
|
||||||
|
core.info(`⚠️ No release information found for ${tagInfo.name}, trying to retrieve tag creation time as fallback.`)
|
||||||
|
const gitHelper = await createCommandManager(repositoryPath)
|
||||||
|
const creationTimeString = await gitHelper.tagCreation(tagInfo.name)
|
||||||
|
const creationTime = moment(creationTimeString)
|
||||||
|
if (creationTimeString !== null && creationTime.isValid()) {
|
||||||
|
tagInfo.date = creationTime
|
||||||
|
core.info(
|
||||||
|
`ℹ️ Resolved tag creation time (${creationTimeString}) from 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
core.info(
|
||||||
|
`⚠️ Could not retrieve tag creation time via git cli 'git for-each-ref --format="%(creatordate:rfc)" "refs/tags/${tagInfo.name}'`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return tagInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
import {BaseRepository} from './BaseRepository'
|
||||||
|
import {TagInfo} from '../pr-collector/tags'
|
||||||
|
import {CommentInfo, PullRequestInfo} from '../pr-collector/pullRequests'
|
||||||
|
import {DiffInfo} from '../pr-collector/commits'
|
||||||
|
import {Api, PullRequest, PullReview, giteaApi} from 'gitea-js'
|
||||||
|
import moment from 'moment'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import {createCommandManager} from '../pr-collector/gitHelper'
|
||||||
|
|
||||||
|
interface Pulls {
|
||||||
|
closed: PullRequest[]
|
||||||
|
open: PullRequest[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GiteaRepository extends BaseRepository {
|
||||||
|
private api: Api<unknown>
|
||||||
|
|
||||||
|
get defaultUrl(): string {
|
||||||
|
return 'https://gitea.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
get homeUrl(): string {
|
||||||
|
return 'https://gitea.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(token: string, url: string | undefined, repositoryPath: string) {
|
||||||
|
super(token, url, repositoryPath)
|
||||||
|
this.url = url || this.defaultUrl
|
||||||
|
this.api = giteaApi(this.url, {
|
||||||
|
token
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo> {
|
||||||
|
const response = await this.api.repos.repoGetTag(owner, repo, tagInfo.name)
|
||||||
|
|
||||||
|
if (response.error === null) {
|
||||||
|
if (response.data.commit) {
|
||||||
|
tagInfo.date = moment(response.data.commit.created)
|
||||||
|
core.info(`ℹ️ Retrieved information about the release associated with ${tagInfo.name} from the Gitea API`)
|
||||||
|
return tagInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await this.getTagByCreateTime(repositoryPath, tagInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBetweenDates(
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
fromDate: moment.Moment,
|
||||||
|
toDate: moment.Moment,
|
||||||
|
maxPullRequests: number
|
||||||
|
): Promise<PullRequestInfo[]> {
|
||||||
|
const mergedPRs: PullRequestInfo[] = []
|
||||||
|
await this.getAllPullRequest(owner, repo, 'closed', maxPullRequests)
|
||||||
|
|
||||||
|
for (const pr of GiteaRepository.pulls.closed.filter(p => !!p.merged_at)) {
|
||||||
|
if (moment(pr.closed_at) > fromDate && moment(pr.closed_at) < toDate) {
|
||||||
|
mergedPRs.push(this.mapPullRequest(pr, 'merged'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mergedPRs
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapPullRequest(pr: PullRequest, status: 'open' | 'merged' = 'open'): PullRequestInfo {
|
||||||
|
return {
|
||||||
|
number: pr.number || 0,
|
||||||
|
title: pr.title || '',
|
||||||
|
htmlURL: pr.html_url || '',
|
||||||
|
baseBranch: pr.base?.repo?.default_branch || '',
|
||||||
|
branch: pr.merge_base || '',
|
||||||
|
mergedAt: pr.merged_at ? moment(pr.merged_at) : undefined,
|
||||||
|
mergeCommitSha: pr.merge_commit_sha || '',
|
||||||
|
author: pr.user?.login || '',
|
||||||
|
repoName: pr.base?.repo?.full_name || '',
|
||||||
|
labels: pr.labels?.map(label => label.name) as string[],
|
||||||
|
milestone: pr.milestone?.title || '',
|
||||||
|
body: pr.body || '',
|
||||||
|
assignees: pr.assignees?.map(user => user.full_name) as string[],
|
||||||
|
requestedReviewers: pr.requested_reviewers?.map(user => user.full_name) as string[],
|
||||||
|
approvedReviewers: [],
|
||||||
|
createdAt: moment(pr.created_at),
|
||||||
|
status,
|
||||||
|
reviews: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WARNING: This does not actually get the diff from the remote, as Gitea does not offer a compareable API.
|
||||||
|
* This uses the local repository to get the diff. NOTE: As such, gitea integration requires the repo available.
|
||||||
|
*/
|
||||||
|
async getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
|
let changedFilesCount = 0
|
||||||
|
let additionCount = 0
|
||||||
|
let deletionCount = 0
|
||||||
|
const changeCount = 0
|
||||||
|
let commitCount = 0
|
||||||
|
|
||||||
|
const gitHelper = await createCommandManager(this.repositoryPath)
|
||||||
|
|
||||||
|
// Get the diff stats between the two branches/commits
|
||||||
|
const diffStat = await gitHelper.execGit(['diff', '--stat', `${base}...${head}`])
|
||||||
|
const diffStatLines = diffStat.stdout.split('\n')
|
||||||
|
|
||||||
|
for (const line of diffStatLines) {
|
||||||
|
// Extract the addition and deletion counts from each line of the git diff output
|
||||||
|
const match = line.match(/(\d+) insertions?\(\+\), (\d+) deletions?\(-\)/)
|
||||||
|
if (match) {
|
||||||
|
additionCount += parseInt(match[1], 10)
|
||||||
|
deletionCount += parseInt(match[2], 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the list of changed files
|
||||||
|
const diffNameOnly = await gitHelper.execGit(['diff', '--name-only', `${base}...${head}`])
|
||||||
|
const changedFiles = diffNameOnly.stdout.split('\n')
|
||||||
|
changedFilesCount = changedFiles.length - 1 // Subtract one for the empty line at the end
|
||||||
|
|
||||||
|
// Get the commit count between the two branches/commits
|
||||||
|
const logCount = await gitHelper.execGit(['rev-list', '--count', `${base}...${head}`])
|
||||||
|
commitCount = parseInt(logCount.stdout.trim(), 10)
|
||||||
|
|
||||||
|
// Now let's get the commit logs between the two branches/commits
|
||||||
|
const log = await gitHelper.execGit(['log', '--pretty=format:%H||||%an||||%ae||||%ad||||%cn||||%ce||||%cd||||%s', `${base}...${head}`])
|
||||||
|
const commitLogs = log.stdout.trim().split('\n')
|
||||||
|
|
||||||
|
// Process commit logs
|
||||||
|
const commitInfo = commitLogs.map(commitLog => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const [sha, authorName, authorEmail, authorDate, committerName, committerEmail, committerDate, subject] = commitLog.split('||||')
|
||||||
|
return {
|
||||||
|
sha,
|
||||||
|
summary: subject,
|
||||||
|
message: '', // This would require another git command to get the full message if needed
|
||||||
|
author: authorName,
|
||||||
|
authorDate: moment(authorDate, 'ddd MMM DD HH:mm:ss YYYY ZZ', false),
|
||||||
|
committer: committerName,
|
||||||
|
commitDate: moment(committerDate, 'ddd MMM DD HH:mm:ss YYYY ZZ', false),
|
||||||
|
prNumber: undefined // This is not available directly from git, would require additional logic to associate commits with PRs
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
changedFiles: changedFilesCount,
|
||||||
|
additions: additionCount,
|
||||||
|
deletions: deletionCount,
|
||||||
|
changes: changeCount,
|
||||||
|
commits: commitCount,
|
||||||
|
commitInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static pulls: Pulls = {
|
||||||
|
closed: [],
|
||||||
|
open: []
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getAllPullRequest(owner: string, repo: string, state: 'closed' | 'open', maxPullRequests: number): Promise<void> {
|
||||||
|
if (GiteaRepository.pulls[state].length === 0) {
|
||||||
|
let page = 1
|
||||||
|
let count = 0
|
||||||
|
while (count < maxPullRequests) {
|
||||||
|
const limit = Math.min(50, maxPullRequests)
|
||||||
|
const response = await this.api.repos.repoListPullRequests(owner, repo, {
|
||||||
|
sort: 'recentupdate',
|
||||||
|
state,
|
||||||
|
limit,
|
||||||
|
page
|
||||||
|
})
|
||||||
|
if (response.error === null) {
|
||||||
|
GiteaRepository.pulls[state].push(...response.data)
|
||||||
|
} else {
|
||||||
|
core.error(`ℹ️ Some errors. ${response.error.message}`)
|
||||||
|
}
|
||||||
|
page++
|
||||||
|
count += response.data.length
|
||||||
|
if (response.data.length === 0) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getForCommitHash(owner: string, repo: string, commit_sha: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
|
const mergedPRs: PullRequestInfo[] = []
|
||||||
|
await this.getAllPullRequest(owner, repo, 'closed', maxPullRequests)
|
||||||
|
|
||||||
|
for (const pr of GiteaRepository.pulls.closed) {
|
||||||
|
if (pr.merge_commit_sha === commit_sha) {
|
||||||
|
mergedPRs.push(this.mapPullRequest(pr, pr.merged_at ? 'merged' : 'open'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.debug(`Completed fetching PRs from API. Fetched: ${mergedPRs.length}`)
|
||||||
|
|
||||||
|
return mergedPRs
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
|
await this.getAllPullRequest(owner, repo, 'open', maxPullRequests)
|
||||||
|
|
||||||
|
const openPrs: PullRequestInfo[] = []
|
||||||
|
for (const pr of GiteaRepository.pulls.open) {
|
||||||
|
openPrs.push(this.mapPullRequest(pr, 'open'))
|
||||||
|
}
|
||||||
|
return openPrs
|
||||||
|
}
|
||||||
|
|
||||||
|
async getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void> {
|
||||||
|
const prReviews: CommentInfo[] = []
|
||||||
|
const response = await this.api.repos.repoListPullReviews(owner, repo, pr.number, {})
|
||||||
|
if (response.error === null) {
|
||||||
|
for (const comment of response.data) {
|
||||||
|
prReviews.push(this.mapComment(comment))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
core.error(`ℹ️ Some errors. ${response.error.message}`)
|
||||||
|
}
|
||||||
|
pr.reviews = prReviews
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapComment = (comment: PullReview): CommentInfo => ({
|
||||||
|
id: comment.id || 0,
|
||||||
|
htmlURL: comment.html_url || '',
|
||||||
|
submittedAt: comment.submitted_at ? moment(comment.submitted_at) : undefined,
|
||||||
|
author: comment.user?.login || '',
|
||||||
|
body: comment.body || '',
|
||||||
|
state: comment.state
|
||||||
|
})
|
||||||
|
|
||||||
|
async getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]> {
|
||||||
|
core.debug(`Start to get tag from gitea`)
|
||||||
|
const response = await this.api.repos.repoListTags(owner, repo, {
|
||||||
|
limit: maxTagsToFetch
|
||||||
|
})
|
||||||
|
const tagsInfo: TagInfo[] = []
|
||||||
|
if (response.error === null) {
|
||||||
|
for (const tag of response.data) {
|
||||||
|
tagsInfo.push({
|
||||||
|
name: tag.name || '',
|
||||||
|
commit: tag.commit?.sha
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
core.error(`ℹ️ Some errors. ${response.error.message}`)
|
||||||
|
}
|
||||||
|
core.info(`ℹ️ Found ${tagsInfo.length} (fetching max: ${maxTagsToFetch}) tags from the GitHub API for ${owner}/${repo}`)
|
||||||
|
return tagsInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
import {BaseRepository} from './BaseRepository'
|
||||||
|
import {Octokit, RestEndpointMethodTypes} from '@octokit/rest'
|
||||||
|
import {HttpsProxyAgent} from 'https-proxy-agent'
|
||||||
|
import * as core from '@actions/core'
|
||||||
|
import {TagInfo} from '../pr-collector/tags'
|
||||||
|
import moment from 'moment/moment'
|
||||||
|
import {DiffInfo} from '../pr-collector/commits'
|
||||||
|
import {CommentInfo, PullData, PullRequestInfo, PullReviewsData, PullsListData} from '../pr-collector/pullRequests'
|
||||||
|
import {Unpacked} from '../pr-collector/utils'
|
||||||
|
|
||||||
|
export class GithubRepository extends BaseRepository {
|
||||||
|
async getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
|
let changedFilesCount = 0
|
||||||
|
let additionCount = 0
|
||||||
|
let deletionCount = 0
|
||||||
|
let changeCount = 0
|
||||||
|
let commitCount = 0
|
||||||
|
|
||||||
|
// Fetch comparisons recursively until we don't find any commits
|
||||||
|
// This is because the GitHub API limits the number of commits returned in a single response.
|
||||||
|
let commits: RestEndpointMethodTypes['repos']['compareCommits']['response']['data']['commits'] = []
|
||||||
|
let compareHead = head
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
const compareResult = await this.octokit.repos.compareCommits({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
base,
|
||||||
|
head: compareHead
|
||||||
|
})
|
||||||
|
if (compareResult.data.total_commits === 0) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
changedFilesCount += compareResult.data.files?.length ?? 0
|
||||||
|
const files = compareResult.data.files
|
||||||
|
if (files !== undefined) {
|
||||||
|
for (const file of files) {
|
||||||
|
additionCount += file.additions
|
||||||
|
deletionCount += file.deletions
|
||||||
|
changeCount += file.changes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commitCount += compareResult.data.commits.length
|
||||||
|
commits = compareResult.data.commits.concat(commits)
|
||||||
|
compareHead = `${commits[0].sha}^`
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`ℹ️ Found ${commits.length} commits from the GitHub API for ${owner}/${repo}`)
|
||||||
|
|
||||||
|
return {
|
||||||
|
changedFiles: changedFilesCount,
|
||||||
|
additions: additionCount,
|
||||||
|
deletions: deletionCount,
|
||||||
|
changes: changeCount,
|
||||||
|
commits: commitCount,
|
||||||
|
commitInfo: commits
|
||||||
|
.filter(commit => commit.sha)
|
||||||
|
.map(commit => ({
|
||||||
|
sha: commit.sha || '',
|
||||||
|
summary: commit.commit.message.split('\n')[0],
|
||||||
|
message: commit.commit.message,
|
||||||
|
author: commit.author?.login || '',
|
||||||
|
authorDate: moment(commit.commit.author?.date),
|
||||||
|
committer: commit.committer?.login || '',
|
||||||
|
commitDate: moment(commit.commit.committer?.date),
|
||||||
|
prNumber: undefined
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getForCommitHash(owner: string, repo: string, commit_sha: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
|
const mergedPRs: PullRequestInfo[] = []
|
||||||
|
const options = this.octokit.repos.listPullRequestsAssociatedWithCommit.endpoint.merge({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
commit_sha,
|
||||||
|
per_page: `${Math.min(10, maxPullRequests)}`,
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
|
||||||
|
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||||
|
const prs: PullsListData = response.data as PullsListData
|
||||||
|
|
||||||
|
for (const pr of prs) {
|
||||||
|
mergedPRs.push(this.mapPullRequest(pr, pr.merged_at ? 'merged' : 'open'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mergedPRs
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBetweenDates(
|
||||||
|
owner: string,
|
||||||
|
repo: string,
|
||||||
|
fromDate: moment.Moment,
|
||||||
|
toDate: moment.Moment,
|
||||||
|
maxPullRequests: number
|
||||||
|
): Promise<PullRequestInfo[]> {
|
||||||
|
const mergedPRs: PullRequestInfo[] = []
|
||||||
|
const options = this.octokit.pulls.list.endpoint.merge({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
state: 'closed',
|
||||||
|
sort: 'merged',
|
||||||
|
per_page: `${Math.min(100, maxPullRequests)}`,
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||||
|
const prs: PullsListData = response.data as PullsListData
|
||||||
|
|
||||||
|
for (const pr of prs.filter(p => !!p.merged_at)) {
|
||||||
|
mergedPRs.push(this.mapPullRequest(pr, 'merged'))
|
||||||
|
}
|
||||||
|
if (mergedPRs.length >= maxPullRequests) {
|
||||||
|
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests} (1)`)
|
||||||
|
break // bail out early to not keep iterating forever
|
||||||
|
} else if (prs.length > 0) {
|
||||||
|
if (this.fetchedEnough(prs, fromDate)) {
|
||||||
|
return mergedPRs // bail out early to not keep iterating on PRs super old
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
core.debug(`⚠️ No more PRs retrieved from API. Fetched so far: ${mergedPRs.length}`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mergedPRs
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
|
const openPrs: PullRequestInfo[] = []
|
||||||
|
const options = this.octokit.pulls.list.endpoint.merge({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
state: 'open',
|
||||||
|
sort: 'created',
|
||||||
|
per_page: '100',
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
|
||||||
|
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||||
|
const prs: PullsListData = response.data as PullsListData
|
||||||
|
|
||||||
|
for (const pr of prs) {
|
||||||
|
openPrs.push(this.mapPullRequest(pr, 'open'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstPR = prs[0]
|
||||||
|
if (firstPR === undefined || openPrs.length >= maxPullRequests) {
|
||||||
|
if (openPrs.length >= maxPullRequests) {
|
||||||
|
core.warning(`⚠️ Reached 'maxPullRequests' count ${maxPullRequests} (2)`)
|
||||||
|
}
|
||||||
|
break // bail out early to not keep iterating forever
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return openPrs
|
||||||
|
}
|
||||||
|
|
||||||
|
async getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void> {
|
||||||
|
const options = this.octokit.pulls.listReviews.endpoint.merge({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number: pr.number,
|
||||||
|
sort: 'created',
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
const prReviews: CommentInfo[] = []
|
||||||
|
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||||
|
const comments: PullReviewsData = response.data as PullReviewsData
|
||||||
|
|
||||||
|
for (const comment of comments) {
|
||||||
|
prReviews.push(this.mapComment(comment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pr.reviews = prReviews
|
||||||
|
}
|
||||||
|
|
||||||
|
get defaultUrl(): string {
|
||||||
|
return 'https://api.github.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
get homeUrl(): string {
|
||||||
|
return this.url?.replace('api.', '') || 'https://github.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
private octokit: Octokit
|
||||||
|
|
||||||
|
constructor(token: string, url: string | undefined, repositoryPath: string) {
|
||||||
|
super(token, url, repositoryPath)
|
||||||
|
this.url = url || this.defaultUrl
|
||||||
|
|
||||||
|
// load octokit instance
|
||||||
|
this.octokit = new Octokit({
|
||||||
|
auth: `token ${this.token}`,
|
||||||
|
baseUrl: this.url
|
||||||
|
})
|
||||||
|
if (this.proxy) {
|
||||||
|
const agent = new HttpsProxyAgent(this.proxy)
|
||||||
|
this.octokit.hook.before('request', options => {
|
||||||
|
if (this.noProxyArray.includes(options.request.hostname)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
options.request.agent = agent
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]> {
|
||||||
|
const tagsInfo: TagInfo[] = []
|
||||||
|
const options = this.octokit.repos.listTags.endpoint.merge({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
direction: 'desc',
|
||||||
|
per_page: 100
|
||||||
|
})
|
||||||
|
|
||||||
|
for await (const response of this.octokit.paginate.iterator(options)) {
|
||||||
|
type TagsListData = RestEndpointMethodTypes['repos']['listTags']['response']['data']
|
||||||
|
const tags: TagsListData = response.data as TagsListData
|
||||||
|
|
||||||
|
for (const tag of tags) {
|
||||||
|
tagsInfo.push({
|
||||||
|
name: tag.name,
|
||||||
|
commit: tag.commit.sha
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// for performance only fetch newest maxTagsToFetch tags!!
|
||||||
|
if (tagsInfo.length >= maxTagsToFetch) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`ℹ️ Found ${tagsInfo.length} (fetching max: ${maxTagsToFetch}) tags from the GitHub API for ${owner}/${repo}`)
|
||||||
|
return tagsInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo> {
|
||||||
|
const options = this.octokit.repos.getReleaseByTag.endpoint.merge({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
tag: tagInfo.name
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await this.octokit.request(options)
|
||||||
|
type ReleaseInformation = RestEndpointMethodTypes['repos']['getReleaseByTag']['response']['data']
|
||||||
|
|
||||||
|
const release: ReleaseInformation = response.data as ReleaseInformation
|
||||||
|
tagInfo.date = moment(release.created_at)
|
||||||
|
core.info(`ℹ️ Retrieved information about the release associated with ${tagInfo.name} from the GitHub API`)
|
||||||
|
} catch (error) {
|
||||||
|
tagInfo = await this.getTagByCreateTime(repositoryPath, tagInfo)
|
||||||
|
}
|
||||||
|
return tagInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// helper function to add a special open label to prs not merged.
|
||||||
|
private attachSpecialLabels(status: 'open' | 'merged', labels: string[]): string[] {
|
||||||
|
labels.push(`--rcba-${status}`)
|
||||||
|
return labels
|
||||||
|
}
|
||||||
|
|
||||||
|
private mapPullRequest = (pr: PullData | Unpacked<PullsListData>, status: 'open' | 'merged' = 'open'): PullRequestInfo => ({
|
||||||
|
number: pr.number,
|
||||||
|
title: pr.title,
|
||||||
|
htmlURL: pr.html_url,
|
||||||
|
baseBranch: pr.base.ref,
|
||||||
|
branch: pr.head.ref,
|
||||||
|
createdAt: moment(pr.created_at),
|
||||||
|
mergedAt: pr.merged_at ? moment(pr.merged_at) : undefined,
|
||||||
|
mergeCommitSha: pr.merge_commit_sha || '',
|
||||||
|
author: pr.user?.login || '',
|
||||||
|
repoName: pr.base.repo.full_name,
|
||||||
|
labels: this.attachSpecialLabels(status, pr.labels?.map(lbl => lbl.name?.toLocaleLowerCase('en') || '') || []),
|
||||||
|
milestone: pr.milestone?.title || '',
|
||||||
|
body: pr.body || '',
|
||||||
|
assignees: pr.assignees?.map(asignee => asignee?.login || '') || [],
|
||||||
|
requestedReviewers: pr.requested_reviewers?.map(reviewer => reviewer?.login || '') || [],
|
||||||
|
approvedReviewers: [],
|
||||||
|
reviews: undefined,
|
||||||
|
status
|
||||||
|
})
|
||||||
|
|
||||||
|
private mapComment = (comment: Unpacked<PullReviewsData>): CommentInfo => ({
|
||||||
|
id: comment.id,
|
||||||
|
htmlURL: comment.html_url,
|
||||||
|
submittedAt: comment.submitted_at ? moment(comment.submitted_at) : undefined,
|
||||||
|
author: comment.user?.login || '',
|
||||||
|
body: comment.body,
|
||||||
|
state: comment.state
|
||||||
|
})
|
||||||
|
|
||||||
|
private fetchedEnough(pullRequests: PullsListData, fromDate: moment.Moment): boolean {
|
||||||
|
for (let i = 0; i < Math.min(pullRequests.length, 3); i++) {
|
||||||
|
const firstPR = pullRequests[i]
|
||||||
|
if (!firstPR.merged_at) {
|
||||||
|
// no merged_at timestamp -> look for the next
|
||||||
|
} else if (fromDate.isAfter(moment(firstPR.merged_at))) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
break // not enough PRs yet, go further
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -11,7 +11,7 @@ import {
|
|||||||
} from './pr-collector/pullRequests'
|
} from './pr-collector/pullRequests'
|
||||||
import {DiffInfo} from './pr-collector/commits'
|
import {DiffInfo} from './pr-collector/commits'
|
||||||
import {validateTransformer} from './pr-collector/regexUtils'
|
import {validateTransformer} from './pr-collector/regexUtils'
|
||||||
import {Transformer, RegexTransformer} from './pr-collector/types'
|
import {RegexTransformer, Transformer} from './pr-collector/types'
|
||||||
import {ReleaseNotesOptions} from './releaseNotesBuilder'
|
import {ReleaseNotesOptions} from './releaseNotesBuilder'
|
||||||
import {matchesRules} from './regexUtils'
|
import {matchesRules} from './regexUtils'
|
||||||
|
|
||||||
@@ -388,7 +388,7 @@ function fillAdditionalPlaceholders(
|
|||||||
}
|
}
|
||||||
placeholderMap.set(
|
placeholderMap.set(
|
||||||
'RELEASE_DIFF',
|
'RELEASE_DIFF',
|
||||||
`https://github.com/${options.owner}/${options.repo}/compare/${options.fromTag.name}...${options.toTag.name}`
|
`${options.repositoryUtils.homeUrl}/${options.owner}/${options.repo}/compare/${options.fromTag.name}...${options.toTag.name}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -7,6 +7,7 @@ import {DiffInfo} from './pr-collector/commits'
|
|||||||
import {PullRequestInfo} from './pr-collector/pullRequests'
|
import {PullRequestInfo} from './pr-collector/pullRequests'
|
||||||
import {Data, ReleaseNotesOptions} from './releaseNotesBuilder'
|
import {Data, ReleaseNotesOptions} from './releaseNotesBuilder'
|
||||||
import {env} from 'process'
|
import {env} from 'process'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the repository path, relatively to the GITHUB_WORKSPACE
|
* Resolves the repository path, relatively to the GITHUB_WORKSPACE
|
||||||
*/
|
*/
|
||||||
@@ -40,13 +41,21 @@ export function writeCacheData(data: Data, cacheOutput: string | null): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(cacheFile, JSON.stringify(data))
|
// use replacer to not cache the repositoryUtils (as that would contain token information)
|
||||||
|
fs.writeFileSync(cacheFile, JSON.stringify(data, replacer))
|
||||||
core.setOutput(`cache`, cacheFile)
|
core.setOutput(`cache`, cacheFile)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.warning(`Failed to write cache file. (${error})`)
|
core.warning(`Failed to write cache file. (${error})`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
function replacer(key: string, value: any): any {
|
||||||
|
if (key === 'repositoryUtils') return undefined
|
||||||
|
if (key === 'token') return undefined
|
||||||
|
else return value
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the exported information from a previous run of the `release-changelog-builder-action`.
|
* Retrieves the exported information from a previous run of the `release-changelog-builder-action`.
|
||||||
* If available, return a [ReleaseNotesData].
|
* If available, return a [ReleaseNotesData].
|
||||||
|
|||||||
+2
-2
@@ -7,7 +7,7 @@
|
|||||||
"strict": true, /* Enable all strict type-checking options. */
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||||
"lib": [ "ES2021.String" ] /* Enable custom `ES2021.String` extension in typescript for `replaceAll` */
|
"lib": [ "ES2021.String", "dom"] /* Enable custom `ES2021.String` extension in typescript for `replaceAll` */
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "**/*.test.ts", "pr-collector"]
|
"exclude": ["node_modules", "**/*.test.ts", "**/**/*.test.ts", "src/pr-collector"],
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user