Merge pull request #1460 from mikepenz/feature/1459
Add new `offlineMode`
This commit is contained in:
@@ -16,6 +16,9 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 100
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- name: Set Node.js 20.x
|
- name: Set Node.js 20.x
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
@@ -32,6 +35,14 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Publish Test Report
|
||||||
|
uses: mikepenz/action-junit-report@v5
|
||||||
|
if: success() || failure() # always run even if the previous step fails
|
||||||
|
with:
|
||||||
|
report_paths: 'junit.xml'
|
||||||
|
comment: true
|
||||||
|
detailed_summary: true
|
||||||
|
|
||||||
test:
|
test:
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
@@ -227,6 +227,7 @@ Depending on the use-case additional settings can be provided to the action
|
|||||||
| `fetchReleaseInformation` | Will enable fetching additional release information from tags. Default: false |
|
| `fetchReleaseInformation` | Will enable fetching additional release information from tags. Default: false |
|
||||||
| `fetchReviews` | Will enable fetching the reviews on of the PR. Default: false |
|
| `fetchReviews` | Will enable fetching the reviews on of the PR. Default: false |
|
||||||
| `mode` | Defines the mode used to retrieve the information. Available options: [`PR`, `COMMIT`, `HYBRID`]. Defaults to `PR`. Hybrid mode treats commits like pull requests. Commit mode is a special configuration for projects which work without PRs. Uses commit messages as changelog. This mode looses access to information only available for PRs. Formerly set as `commitMode: true`, this setting is now deprecated and should be converted to `mode: "COMMIT"`. Note: the commit or hybrid modes are not fully supported. |
|
| `mode` | Defines the mode used to retrieve the information. Available options: [`PR`, `COMMIT`, `HYBRID`]. Defaults to `PR`. Hybrid mode treats commits like pull requests. Commit mode is a special configuration for projects which work without PRs. Uses commit messages as changelog. This mode looses access to information only available for PRs. Formerly set as `commitMode: true`, this setting is now deprecated and should be converted to `mode: "COMMIT"`. Note: the commit or hybrid modes are not fully supported. |
|
||||||
|
| `offlineMode` | [EXPERIMENTAL] Enables offline mode which disables API requests to GitHub or Gitea. Only works with commitMode and retrieves tags and diffs from the local repository. Default: false |
|
||||||
| `exportCache` | Will enable exporting the fetched PR information to a cache, which can be re-used by later runs. Default: false |
|
| `exportCache` | Will enable exporting the fetched PR information to a cache, which can be re-used by later runs. Default: false |
|
||||||
| `exportOnly` | When enabled, will result in only exporting the cache, without generating a changelog. Default: false (Requires `exportCache` to be enabled) |
|
| `exportOnly` | When enabled, will result in only exporting the cache, without generating 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. |
|
||||||
|
|||||||
+52
-5
@@ -12,9 +12,21 @@ clear()
|
|||||||
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
|
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
|
||||||
const __dirname = path.dirname(__filename); // get the name of the directory
|
const __dirname = path.dirname(__filename); // get the name of the directory
|
||||||
|
|
||||||
test('missing values should result in failure', () => {
|
function resetEnv(): void {
|
||||||
expect.assertions(1)
|
process.env['INPUT_CONFIGURATION'] = ''
|
||||||
|
process.env['INPUT_OWNER'] = ''
|
||||||
|
process.env['INPUT_REPO'] = ''
|
||||||
|
process.env['INPUT_MODE'] = ''
|
||||||
|
process.env['INPUT_OFFLINEMODE'] = ''
|
||||||
|
process.env['INPUT_OUTPUTFILE'] = ''
|
||||||
|
process.env['INPUT_CACHE'] = ''
|
||||||
|
process.env['GITHUB_WORKSPACE'] = ''
|
||||||
|
process.env['INPUT_FROMTAG'] = ''
|
||||||
|
process.env['INPUT_TOTAG'] = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
test('missing values should result in failure', () => {
|
||||||
|
resetEnv()
|
||||||
process.env['GITHUB_WORKSPACE'] = '.'
|
process.env['GITHUB_WORKSPACE'] = '.'
|
||||||
process.env['INPUT_OWNER'] = undefined
|
process.env['INPUT_OWNER'] = undefined
|
||||||
process.env['INPUT_CONFIGURATION'] = 'configs/configuration.json'
|
process.env['INPUT_CONFIGURATION'] = 'configs/configuration.json'
|
||||||
@@ -23,13 +35,14 @@ test('missing values should result in failure', () => {
|
|||||||
env: process.env
|
env: process.env
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
cp.execSync(`node ${ip}`, options).toString()
|
cp.execFileSync('node', [ip], options).toString()
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
expect(true).toBe(true)
|
expect(true).toBe(true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
test('complete input should succeed', () => {
|
test('complete input should succeed', () => {
|
||||||
|
resetEnv()
|
||||||
process.env['GITHUB_WORKSPACE'] = '.'
|
process.env['GITHUB_WORKSPACE'] = '.'
|
||||||
process.env['INPUT_CONFIGURATION'] = 'configuration.json'
|
process.env['INPUT_CONFIGURATION'] = 'configuration.json'
|
||||||
process.env['INPUT_OWNER'] = 'mikepenz'
|
process.env['INPUT_OWNER'] = 'mikepenz'
|
||||||
@@ -48,8 +61,9 @@ test('complete input should succeed', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test('should write result to file', () => {
|
test('should write result to file', () => {
|
||||||
|
resetEnv()
|
||||||
process.env['GITHUB_WORKSPACE'] = '.'
|
process.env['GITHUB_WORKSPACE'] = '.'
|
||||||
process.env['INPUT_CONFIGURATION'] = 'configuration.json'
|
process.env['INPUT_CONFIGURATION'] = 'configs/configuration.json'
|
||||||
process.env['INPUT_OWNER'] = 'mikepenz'
|
process.env['INPUT_OWNER'] = 'mikepenz'
|
||||||
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'
|
||||||
@@ -61,7 +75,7 @@ test('should write result to file', () => {
|
|||||||
const options: cp.ExecSyncOptions = {
|
const options: cp.ExecSyncOptions = {
|
||||||
env: process.env
|
env: process.env
|
||||||
}
|
}
|
||||||
const result = cp.execSync(`node ${ip}`, options).toString()
|
const result = cp.execFileSync('node', [ip], options).toString()
|
||||||
// should succeed
|
// should succeed
|
||||||
expect(result).toBeDefined()
|
expect(result).toBeDefined()
|
||||||
|
|
||||||
@@ -71,3 +85,36 @@ test('should write result to file', () => {
|
|||||||
|
|
||||||
expect(readOutput.toString()).not.toBe('')
|
expect(readOutput.toString()).not.toBe('')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('offline mode should work with commit mode', () => {
|
||||||
|
resetEnv()
|
||||||
|
// This test verifies that the offlineMode parameter is correctly passed to the configuration
|
||||||
|
// and that the OfflineRepository is used when offlineMode is enabled.
|
||||||
|
|
||||||
|
// Set up environment variables for the test
|
||||||
|
process.env['GITHUB_WORKSPACE'] = '.'
|
||||||
|
process.env['INPUT_CONFIGURATION'] = 'configs/configuration_commit.json'
|
||||||
|
process.env['INPUT_OWNER'] = 'mikepenz'
|
||||||
|
process.env['INPUT_REPO'] = 'release-changelog-builder-action'
|
||||||
|
process.env['INPUT_MODE'] = 'PR'
|
||||||
|
process.env['INPUT_OFFLINEMODE'] = 'true'
|
||||||
|
process.env['INPUT_OUTPUTFILE'] = 'test.md'
|
||||||
|
process.env['INPUT_CACHE'] = ''
|
||||||
|
|
||||||
|
const ip = path.join(__dirname, '..', 'lib', 'main.js')
|
||||||
|
const options: cp.ExecSyncOptions = {
|
||||||
|
env: process.env
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = cp.execFileSync('node', [ip], options).toString()
|
||||||
|
// should succeed
|
||||||
|
expect(result).toBeDefined()
|
||||||
|
|
||||||
|
const readOutput = fs.readFileSync('test.md')
|
||||||
|
fs.unlinkSync('test.md')
|
||||||
|
|
||||||
|
expect(readOutput.toString()).not.toBe("- no changes")
|
||||||
|
expect(readOutput.toString()).not.toBe('')
|
||||||
|
|
||||||
|
console.log('Offline mode test succeeded')
|
||||||
|
})
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* @file offlineMode.test.ts
|
||||||
|
* @description Test file for validating the behavior of the new offline mode feature.
|
||||||
|
*
|
||||||
|
* This test verifies that:
|
||||||
|
* 1. The offlineMode parameter is correctly passed to the configuration
|
||||||
|
* 2. The OfflineRepository is used when offlineMode is enabled
|
||||||
|
* 3. Local tag and diff retrieval works correctly
|
||||||
|
*
|
||||||
|
* To run this test:
|
||||||
|
* npm run test-offline
|
||||||
|
*
|
||||||
|
* Note: This test requires a local git repository with tags to work properly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {mergeConfiguration, resolveConfiguration} from '../../src/utils.js'
|
||||||
|
import {ReleaseNotesBuilder} from '../../src/releaseNotesBuilder.js'
|
||||||
|
import {OfflineRepository} from '../../src/repositories/OfflineRepository.js'
|
||||||
|
import {jest} from '@jest/globals'
|
||||||
|
|
||||||
|
jest.setTimeout(180000)
|
||||||
|
|
||||||
|
// This test validates the behavior of the new offline mode
|
||||||
|
test('Test offline mode functionality', async () => {
|
||||||
|
// Define the configuration file to use
|
||||||
|
const configuration = mergeConfiguration(undefined, resolveConfiguration('', 'configs/configuration_commit.json'))
|
||||||
|
|
||||||
|
// Set offlineMode to true in the configuration
|
||||||
|
configuration.offlineMode = true
|
||||||
|
|
||||||
|
// Create an instance of OfflineRepository
|
||||||
|
const offlineRepository = new OfflineRepository( '.')
|
||||||
|
|
||||||
|
const releaseNotesBuilder = new ReleaseNotesBuilder(
|
||||||
|
null, // The base url used for the API requests (not needed for offline mode)
|
||||||
|
offlineRepository, // Use the OfflineRepository implementation
|
||||||
|
'.', // Root path to the checked out sources
|
||||||
|
'mikepenz', // The owner of the repo to test
|
||||||
|
'release-changelog-builder-action', // The repository name - using this repo itself for the test
|
||||||
|
null, // fromTag - will be resolved automatically
|
||||||
|
null, // toTag - will be resolved automatically
|
||||||
|
false, // includeOpen - not supported in offline mode
|
||||||
|
false, // failOnError
|
||||||
|
false, // ignorePrePrerelease
|
||||||
|
false, // fetchViaCommits - not needed in offline mode
|
||||||
|
false, // fetchReviewers - not supported in offline mode
|
||||||
|
false, // fetchReleaseInformation
|
||||||
|
false, // fetchReviews - not supported in offline mode
|
||||||
|
'COMMIT', // mode - must be COMMIT for offline mode
|
||||||
|
false, // exportCache
|
||||||
|
false, // exportOnly
|
||||||
|
null, // cache
|
||||||
|
configuration // The configuration to use
|
||||||
|
)
|
||||||
|
|
||||||
|
// Build the changelog
|
||||||
|
const changeLog = await releaseNotesBuilder.build()
|
||||||
|
|
||||||
|
// Verify that a changelog was generated
|
||||||
|
expect(changeLog).toBeDefined()
|
||||||
|
expect(changeLog).not.toBe("- no changes")
|
||||||
|
expect(changeLog?.length).toBeGreaterThan(0)
|
||||||
|
|
||||||
|
// Log the changelog for inspection
|
||||||
|
console.log('Generated changelog in offline mode:')
|
||||||
|
console.log(changeLog)
|
||||||
|
})
|
||||||
@@ -45,6 +45,9 @@ inputs:
|
|||||||
commitMode:
|
commitMode:
|
||||||
description: '[Deprecated] Enables the commit based mode. This mode generates changelogs based on the commits. Please note that this lacks a lot of features only possible with PRs.'
|
description: '[Deprecated] Enables the commit based mode. This mode generates changelogs based on the commits. Please note that this lacks a lot of features only possible with PRs.'
|
||||||
default: "false"
|
default: "false"
|
||||||
|
offlineMode:
|
||||||
|
description: 'Enables offline mode which disables API requests to GitHub or Gitea. Only works with commitMode and retrieves tags and diffs from the local repository.'
|
||||||
|
default: "false"
|
||||||
outputFile:
|
outputFile:
|
||||||
description: 'If defined, the changelog will get written to this file. (relative to the checkout dir)'
|
description: 'If defined, the changelog will get written to this file. (relative to the checkout dir)'
|
||||||
token:
|
token:
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"categories": [
|
||||||
|
{
|
||||||
|
"title": "## 🚀 Features",
|
||||||
|
"labels": ["feature"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🐛 Fixes",
|
||||||
|
"labels": ["fix"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## 🧪 Tests",
|
||||||
|
"labels": ["test"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "## Other",
|
||||||
|
"labels": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sort": "ASC",
|
||||||
|
"template": "${{CHANGELOG}}",
|
||||||
|
"pr_template": "- ${{TITLE}}",
|
||||||
|
"empty_template": "- no changes",
|
||||||
|
"max_pull_requests": 1000,
|
||||||
|
"max_back_track_time_days": 1000
|
||||||
|
}
|
||||||
+160
-5
@@ -16247,7 +16247,7 @@ const toComparators = __nccwpck_require__(4750)
|
|||||||
const maxSatisfying = __nccwpck_require__(5574)
|
const maxSatisfying = __nccwpck_require__(5574)
|
||||||
const minSatisfying = __nccwpck_require__(8595)
|
const minSatisfying = __nccwpck_require__(8595)
|
||||||
const minVersion = __nccwpck_require__(1866)
|
const minVersion = __nccwpck_require__(1866)
|
||||||
const validRange = __nccwpck_require__(7118)
|
const validRange = __nccwpck_require__(4737)
|
||||||
const outside = __nccwpck_require__(280)
|
const outside = __nccwpck_require__(280)
|
||||||
const gtr = __nccwpck_require__(2276)
|
const gtr = __nccwpck_require__(2276)
|
||||||
const ltr = __nccwpck_require__(5213)
|
const ltr = __nccwpck_require__(5213)
|
||||||
@@ -17299,7 +17299,7 @@ module.exports = toComparators
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 7118:
|
/***/ 4737:
|
||||||
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
|
|
||||||
@@ -42022,7 +42022,8 @@ const DefaultConfiguration = {
|
|||||||
},
|
},
|
||||||
base_branches: [], // target branches for the merged PR ignoring PRs with different target branch, by default it will get all PRs
|
base_branches: [], // target branches for the merged PR ignoring PRs with different target branch, by default it will get all PRs
|
||||||
custom_placeholders: [],
|
custom_placeholders: [],
|
||||||
trim_values: false // defines if values are being trimmed prior to inserting
|
trim_values: false, // defines if values are being trimmed prior to inserting
|
||||||
|
offlineMode: false // defines if the action should run in offline mode, disabling API requests
|
||||||
};
|
};
|
||||||
const DefaultCommitConfiguration = {
|
const DefaultCommitConfiguration = {
|
||||||
...DefaultConfiguration,
|
...DefaultConfiguration,
|
||||||
@@ -43626,6 +43627,56 @@ class GitCommandManager {
|
|||||||
const creationDate = await this.execGit(['for-each-ref', '--format="%(creatordate:rfc)"', `refs/tags/${tagName}`]);
|
const creationDate = await this.execGit(['for-each-ref', '--format="%(creatordate:rfc)"', `refs/tags/${tagName}`]);
|
||||||
return creationDate.stdout.trim().replace(/"/g, '');
|
return creationDate.stdout.trim().replace(/"/g, '');
|
||||||
}
|
}
|
||||||
|
async getAllTags() {
|
||||||
|
const tagsOutput = await this.execGit(['tag', '-l']);
|
||||||
|
return tagsOutput.stdout.trim().split('\n').filter(tag => tag.trim() !== '');
|
||||||
|
}
|
||||||
|
async getTagCommit(tagName) {
|
||||||
|
const commitOutput = await this.execGit(['rev-list', '-n', '1', tagName]);
|
||||||
|
return commitOutput.stdout.trim();
|
||||||
|
}
|
||||||
|
async getDiffStats(base, head) {
|
||||||
|
const diffOutput = await this.execGit(['diff', '--numstat', `${base}..${head}`]);
|
||||||
|
const lines = diffOutput.stdout.trim().split('\n').filter(line => line.trim() !== '');
|
||||||
|
let additions = 0;
|
||||||
|
let deletions = 0;
|
||||||
|
for (const line of lines) {
|
||||||
|
const parts = line.split('\t');
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
additions += parseInt(parts[0], 10) || 0;
|
||||||
|
deletions += parseInt(parts[1], 10) || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
changedFiles: lines.length,
|
||||||
|
additions,
|
||||||
|
deletions,
|
||||||
|
changes: additions + deletions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async getCommitsBetween(base, head) {
|
||||||
|
const logOutput = await this.execGit([
|
||||||
|
'log',
|
||||||
|
'--pretty=format:%H|%an|%ae|%aI|%s|%b',
|
||||||
|
`${base}..${head}`
|
||||||
|
]);
|
||||||
|
const lines = logOutput.stdout.trim().split('\n').filter(line => line.trim() !== '');
|
||||||
|
const commits = lines.map(line => {
|
||||||
|
const [sha, authorName, authorEmail, authorDate, subject, body] = line.split('|');
|
||||||
|
return {
|
||||||
|
sha,
|
||||||
|
subject,
|
||||||
|
message: body,
|
||||||
|
author: authorEmail,
|
||||||
|
authorName,
|
||||||
|
authorDate
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
count: commits.length,
|
||||||
|
commits
|
||||||
|
};
|
||||||
|
}
|
||||||
static async createCommandManager(workingDirectory) {
|
static async createCommandManager(workingDirectory) {
|
||||||
const result = new GitCommandManager();
|
const result = new GitCommandManager();
|
||||||
await result.initializeCommandManager(workingDirectory);
|
await result.initializeCommandManager(workingDirectory);
|
||||||
@@ -54933,6 +54984,100 @@ class GiteaRepository extends BaseRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
;// CONCATENATED MODULE: ./lib/repositories/OfflineRepository.js
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class OfflineRepository extends BaseRepository {
|
||||||
|
constructor(repositoryPath) {
|
||||||
|
super("", "offline", repositoryPath);
|
||||||
|
this.url = this.defaultUrl;
|
||||||
|
}
|
||||||
|
get defaultUrl() {
|
||||||
|
return "offline";
|
||||||
|
}
|
||||||
|
get homeUrl() {
|
||||||
|
return "offline";
|
||||||
|
}
|
||||||
|
async getTags(owner, repo, maxTagsToFetch) {
|
||||||
|
core.info(`ℹ️ Retrieving tags from local repository in offline mode`);
|
||||||
|
const gitHelper = await createCommandManager(this.repositoryPath);
|
||||||
|
const tags = await gitHelper.getAllTags();
|
||||||
|
// Limit the number of tags to maxTagsToFetch
|
||||||
|
const limitedTags = tags.slice(0, maxTagsToFetch);
|
||||||
|
// Convert to TagInfo objects
|
||||||
|
const tagInfos = [];
|
||||||
|
for (const tag of limitedTags) {
|
||||||
|
const commit = await gitHelper.getTagCommit(tag);
|
||||||
|
tagInfos.push({
|
||||||
|
name: tag,
|
||||||
|
commit
|
||||||
|
});
|
||||||
|
}
|
||||||
|
core.info(`ℹ️ Retrieved ${tagInfos.length} tags from local repository`);
|
||||||
|
return tagInfos;
|
||||||
|
}
|
||||||
|
async fillTagInformation(repositoryPath, owner, repo, tagInfo) {
|
||||||
|
return this.getTagByCreateTime(repositoryPath, tagInfo);
|
||||||
|
}
|
||||||
|
async getDiffRemote(owner, repo, base, head) {
|
||||||
|
core.info(`ℹ️ Getting diff information from local repository in offline mode`);
|
||||||
|
const gitHelper = await createCommandManager(this.repositoryPath);
|
||||||
|
// Get diff stats
|
||||||
|
const diffStats = await gitHelper.getDiffStats(base, head);
|
||||||
|
// Get commits
|
||||||
|
const commitInfo = await gitHelper.getCommitsBetween(base, head);
|
||||||
|
return {
|
||||||
|
changedFiles: diffStats.changedFiles,
|
||||||
|
additions: diffStats.additions,
|
||||||
|
deletions: diffStats.deletions,
|
||||||
|
changes: diffStats.changes,
|
||||||
|
commits: commitInfo.count,
|
||||||
|
commitInfo: commitInfo.commits.map(commit => ({
|
||||||
|
sha: commit.sha,
|
||||||
|
summary: commit.subject.split('\n')[0],
|
||||||
|
message: commit.message,
|
||||||
|
author: commit.author,
|
||||||
|
authorName: commit.authorName,
|
||||||
|
authorDate: moment(commit.authorDate),
|
||||||
|
committer: "",
|
||||||
|
committerName: "",
|
||||||
|
commitDate: moment(commit.authorDate),
|
||||||
|
prNumber: undefined
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async getForCommitHash(owner, repo, commit_sha, maxPullRequests) {
|
||||||
|
core.info(`⚠️ getForCommitHash not supported in offline mode`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
async getBetweenDates(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
owner,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
repo,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
fromDate,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
toDate,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
maxPullRequests) {
|
||||||
|
core.info(`⚠️ getBetweenDates not supported in offline mode`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async getOpen(owner, repo, maxPullRequests) {
|
||||||
|
core.info(`⚠️ getOpen not supported in offline mode`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async getReviews(owner, repo, pr) {
|
||||||
|
core.info(`⚠️ getReviews not supported in offline mode`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
;// CONCATENATED MODULE: ./lib/main.js
|
;// CONCATENATED MODULE: ./lib/main.js
|
||||||
|
|
||||||
|
|
||||||
@@ -54940,6 +55085,7 @@ class GiteaRepository extends BaseRepository {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
const supportedPlatform = {
|
const supportedPlatform = {
|
||||||
github: GithubRepository,
|
github: GithubRepository,
|
||||||
@@ -54980,7 +55126,13 @@ async function run() {
|
|||||||
core.info(`ℹ️ No configuration provided. Using Defaults.`);
|
core.info(`ℹ️ No configuration provided. Using Defaults.`);
|
||||||
}
|
}
|
||||||
// mode of the action (PR, COMMIT, HYBRID)
|
// mode of the action (PR, COMMIT, HYBRID)
|
||||||
const mode = resolveMode(core.getInput('mode'), core.getInput('commitMode') === 'true');
|
let mode = resolveMode(core.getInput('mode'), core.getInput('commitMode') === 'true');
|
||||||
|
const offlineMode = core.getInput('offlineMode') === 'true';
|
||||||
|
// If offline mode is enabled, ensure commit mode is used
|
||||||
|
if (offlineMode && mode !== 'COMMIT') {
|
||||||
|
core.warning('⚠️ Offline mode requires commit mode. Switching to commit mode.');
|
||||||
|
mode = 'COMMIT';
|
||||||
|
}
|
||||||
core.info(`ℹ️ Running in ${mode} mode.`);
|
core.info(`ℹ️ Running in ${mode} mode.`);
|
||||||
// merge configs, use default values from DefaultConfig on missing definition
|
// merge configs, use default values from DefaultConfig on missing definition
|
||||||
const configuration = mergeConfiguration(configJson, configFile, mode);
|
const configuration = mergeConfiguration(configJson, configFile, mode);
|
||||||
@@ -55003,7 +55155,10 @@ async function run() {
|
|||||||
const exportCache = core.getInput('exportCache') === 'true';
|
const exportCache = core.getInput('exportCache') === 'true';
|
||||||
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);
|
// Use OfflineRepository if offline mode is enabled, otherwise use the selected platform
|
||||||
|
const repositoryUtils = offlineMode
|
||||||
|
? new OfflineRepository(repositoryPath)
|
||||||
|
: new supportedPlatform[platform](token, baseUrl, repositoryPath);
|
||||||
const result = await new ReleaseNotesBuilder(baseUrl, repositoryUtils, repositoryPath, owner, repo, fromTag, toTag, includeOpen, failOnError, ignorePreReleases, fetchViaCommits, fetchReviewers, fetchReleaseInformation, fetchReviews, mode, exportCache, exportOnly, cache, configuration).build();
|
const result = await new ReleaseNotesBuilder(baseUrl, repositoryUtils, repositoryPath, owner, repo, fromTag, toTag, includeOpen, failOnError, ignorePreReleases, fetchViaCommits, fetchReviewers, fetchReleaseInformation, fetchReviews, mode, exportCache, exportOnly, cache, configuration).build();
|
||||||
core.setOutput('changelog', result);
|
core.setOutput('changelog', result);
|
||||||
// write the result in changelog to file if possible
|
// write the result in changelog to file if possible
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
Generated
+47
@@ -36,6 +36,7 @@
|
|||||||
"eslint-plugin-prettier": "^5.4.0",
|
"eslint-plugin-prettier": "^5.4.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-circus": "^29.7.0",
|
"jest-circus": "^29.7.0",
|
||||||
|
"jest-junit": "^16.0.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"prettier": "3.5.3",
|
"prettier": "3.5.3",
|
||||||
"ts-jest": "^29.3.4",
|
"ts-jest": "^29.3.4",
|
||||||
@@ -5932,6 +5933,22 @@
|
|||||||
"fsevents": "^2.3.2"
|
"fsevents": "^2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jest-junit": {
|
||||||
|
"version": "16.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz",
|
||||||
|
"integrity": "sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"mkdirp": "^1.0.4",
|
||||||
|
"strip-ansi": "^6.0.1",
|
||||||
|
"uuid": "^8.3.2",
|
||||||
|
"xml": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jest-leak-detector": {
|
"node_modules/jest-leak-detector": {
|
||||||
"version": "29.7.0",
|
"version": "29.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
|
||||||
@@ -6607,6 +6624,19 @@
|
|||||||
"node": ">=16 || 14 >=14.17"
|
"node": ">=16 || 14 >=14.17"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mkdirp": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"mkdirp": "bin/cmd.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/moment": {
|
"node_modules/moment": {
|
||||||
"version": "2.30.1",
|
"version": "2.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
@@ -8449,6 +8479,16 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/v8-to-istanbul": {
|
"node_modules/v8-to-istanbul": {
|
||||||
"version": "9.3.0",
|
"version": "9.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
|
||||||
@@ -8717,6 +8757,13 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/xml": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
|||||||
+8
-5
@@ -12,11 +12,13 @@
|
|||||||
"format-fix": "eslint --fix src/**.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": "NODE_OPTIONS=--experimental-vm-modules jest",
|
"test": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=default --reporters=jest-junit",
|
||||||
"test-github": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/*.test.ts",
|
"test-main": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/main.test.ts --reporters=default --reporters=jest-junit",
|
||||||
"test-gitea": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/gitea/*.test.ts",
|
"test-github": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/*.test.ts --reporters=default --reporters=jest-junit",
|
||||||
"test-demo": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/demo/*.test.ts",
|
"test-gitea": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/gitea/*.test.ts --reporters=default --reporters=jest-junit",
|
||||||
"all": "npm run build && npm run format && npm run lint && npm run package && npm run test-github"
|
"test-demo": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/demo/*.test.ts --reporters=default --reporters=jest-junit",
|
||||||
|
"test-offline": "NODE_OPTIONS=--experimental-vm-modules jest __tests__/offline/*.test.ts --reporters=default --reporters=jest-junit",
|
||||||
|
"all": "npm run build && npm run format && npm run lint && npm run package && npm run test-github && npm run test-offline"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -63,6 +65,7 @@
|
|||||||
"eslint-plugin-jest": "^28.11.1",
|
"eslint-plugin-jest": "^28.11.1",
|
||||||
"eslint-plugin-prettier": "^5.4.0",
|
"eslint-plugin-prettier": "^5.4.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
|
"jest-junit": "^16.0.0",
|
||||||
"jest-circus": "^29.7.0",
|
"jest-circus": "^29.7.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"prettier": "3.5.3",
|
"prettier": "3.5.3",
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ export const DefaultConfiguration: Configuration = {
|
|||||||
},
|
},
|
||||||
base_branches: [], // target branches for the merged PR ignoring PRs with different target branch, by default it will get all PRs
|
base_branches: [], // target branches for the merged PR ignoring PRs with different target branch, by default it will get all PRs
|
||||||
custom_placeholders: [],
|
custom_placeholders: [],
|
||||||
trim_values: false // defines if values are being trimmed prior to inserting
|
trim_values: false, // defines if values are being trimmed prior to inserting
|
||||||
|
offlineMode: false // defines if the action should run in offline mode, disabling API requests
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DefaultCommitConfiguration: Configuration = {
|
export const DefaultCommitConfiguration: Configuration = {
|
||||||
|
|||||||
+14
-2
@@ -5,6 +5,7 @@ import {ReleaseNotesBuilder} from './releaseNotesBuilder.js'
|
|||||||
import {Configuration} from './configuration.js'
|
import {Configuration} from './configuration.js'
|
||||||
import {GithubRepository} from './repositories/GithubRepository.js'
|
import {GithubRepository} from './repositories/GithubRepository.js'
|
||||||
import {GiteaRepository} from './repositories/GiteaRepository.js'
|
import {GiteaRepository} from './repositories/GiteaRepository.js'
|
||||||
|
import {OfflineRepository} from './repositories/OfflineRepository.js'
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
const supportedPlatform = {
|
const supportedPlatform = {
|
||||||
@@ -52,7 +53,15 @@ async function run(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mode of the action (PR, COMMIT, HYBRID)
|
// mode of the action (PR, COMMIT, HYBRID)
|
||||||
const mode = resolveMode(core.getInput('mode'), core.getInput('commitMode') === 'true')
|
let mode = resolveMode(core.getInput('mode'), core.getInput('commitMode') === 'true')
|
||||||
|
const offlineMode = core.getInput('offlineMode') === 'true'
|
||||||
|
|
||||||
|
// If offline mode is enabled, ensure commit mode is used
|
||||||
|
if (offlineMode && mode !== 'COMMIT') {
|
||||||
|
core.warning('⚠️ Offline mode requires commit mode. Switching to commit mode.')
|
||||||
|
mode = 'COMMIT'
|
||||||
|
}
|
||||||
|
|
||||||
core.info(`ℹ️ Running in ${mode} mode.`)
|
core.info(`ℹ️ Running in ${mode} mode.`)
|
||||||
|
|
||||||
// merge configs, use default values from DefaultConfig on missing definition
|
// merge configs, use default values from DefaultConfig on missing definition
|
||||||
@@ -78,7 +87,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)
|
// Use OfflineRepository if offline mode is enabled, otherwise use the selected platform
|
||||||
|
const repositoryUtils = offlineMode
|
||||||
|
? new OfflineRepository(repositoryPath)
|
||||||
|
: new supportedPlatform[platform](token, baseUrl, repositoryPath)
|
||||||
const result = await new ReleaseNotesBuilder(
|
const result = await new ReleaseNotesBuilder(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
repositoryUtils,
|
repositoryUtils,
|
||||||
|
|||||||
@@ -33,6 +33,80 @@ class GitCommandManager {
|
|||||||
return creationDate.stdout.trim().replace(/"/g, '')
|
return creationDate.stdout.trim().replace(/"/g, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getAllTags(): Promise<string[]> {
|
||||||
|
const tagsOutput = await this.execGit(['tag', '-l'])
|
||||||
|
return tagsOutput.stdout.trim().split('\n').filter(tag => tag.trim() !== '')
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTagCommit(tagName: string): Promise<string> {
|
||||||
|
const commitOutput = await this.execGit(['rev-list', '-n', '1', tagName])
|
||||||
|
return commitOutput.stdout.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDiffStats(base: string, head: string): Promise<{
|
||||||
|
changedFiles: number;
|
||||||
|
additions: number;
|
||||||
|
deletions: number;
|
||||||
|
changes: number;
|
||||||
|
}> {
|
||||||
|
const diffOutput = await this.execGit(['diff', '--numstat', `${base}..${head}`])
|
||||||
|
const lines = diffOutput.stdout.trim().split('\n').filter(line => line.trim() !== '')
|
||||||
|
|
||||||
|
let additions = 0
|
||||||
|
let deletions = 0
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const parts = line.split('\t')
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
additions += parseInt(parts[0], 10) || 0
|
||||||
|
deletions += parseInt(parts[1], 10) || 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
changedFiles: lines.length,
|
||||||
|
additions,
|
||||||
|
deletions,
|
||||||
|
changes: additions + deletions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getCommitsBetween(base: string, head: string): Promise<{
|
||||||
|
count: number;
|
||||||
|
commits: {
|
||||||
|
sha: string;
|
||||||
|
subject: string
|
||||||
|
message: string;
|
||||||
|
author: string;
|
||||||
|
authorName: string;
|
||||||
|
authorDate: string;
|
||||||
|
}[];
|
||||||
|
}> {
|
||||||
|
const logOutput = await this.execGit([
|
||||||
|
'log',
|
||||||
|
'--pretty=format:%H|%an|%ae|%aI|%s|%b',
|
||||||
|
`${base}..${head}`
|
||||||
|
])
|
||||||
|
|
||||||
|
const lines = logOutput.stdout.trim().split('\n').filter(line => line.trim() !== '')
|
||||||
|
const commits = lines.map(line => {
|
||||||
|
const [sha, authorName, authorEmail, authorDate, subject, body] = line.split('|')
|
||||||
|
return {
|
||||||
|
sha,
|
||||||
|
subject,
|
||||||
|
message: body,
|
||||||
|
author: authorEmail,
|
||||||
|
authorName,
|
||||||
|
authorDate
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
count: commits.length,
|
||||||
|
commits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static async createCommandManager(workingDirectory: string): Promise<GitCommandManager> {
|
static async createCommandManager(workingDirectory: string): Promise<GitCommandManager> {
|
||||||
const result = new GitCommandManager()
|
const result = new GitCommandManager()
|
||||||
await result.initializeCommandManager(workingDirectory)
|
await result.initializeCommandManager(workingDirectory)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export interface PullConfiguration {
|
|||||||
sort: Sort | string // "ASC" or "DESC"
|
sort: Sort | string // "ASC" or "DESC"
|
||||||
tag_resolver: TagResolver
|
tag_resolver: TagResolver
|
||||||
base_branches: string[]
|
base_branches: string[]
|
||||||
|
offlineMode?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import * as core from "@actions/core";
|
||||||
|
import moment from "moment";
|
||||||
|
import { BaseRepository } from "./BaseRepository.js";
|
||||||
|
import { TagInfo } from "../pr-collector/tags.js";
|
||||||
|
import { DiffInfo } from "../pr-collector/commits.js";
|
||||||
|
import { PullRequestInfo } from "../pr-collector/pullRequests.js";
|
||||||
|
import { createCommandManager } from "../pr-collector/gitHelper.js";
|
||||||
|
|
||||||
|
export class OfflineRepository extends BaseRepository {
|
||||||
|
|
||||||
|
constructor(repositoryPath: string) {
|
||||||
|
super("", "offline", repositoryPath);
|
||||||
|
this.url = this.defaultUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
get defaultUrl(): string {
|
||||||
|
return "offline";
|
||||||
|
}
|
||||||
|
|
||||||
|
get homeUrl(): string {
|
||||||
|
return "offline";
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTags(owner: string, repo: string, maxTagsToFetch: number): Promise<TagInfo[]> {
|
||||||
|
core.info(`ℹ️ Retrieving tags from local repository in offline mode`);
|
||||||
|
const gitHelper = await createCommandManager(this.repositoryPath);
|
||||||
|
const tags = await gitHelper.getAllTags();
|
||||||
|
|
||||||
|
// Limit the number of tags to maxTagsToFetch
|
||||||
|
const limitedTags = tags.slice(0, maxTagsToFetch);
|
||||||
|
|
||||||
|
// Convert to TagInfo objects
|
||||||
|
const tagInfos: TagInfo[] = [];
|
||||||
|
for (const tag of limitedTags) {
|
||||||
|
const commit = await gitHelper.getTagCommit(tag);
|
||||||
|
tagInfos.push({
|
||||||
|
name: tag,
|
||||||
|
commit
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`ℹ️ Retrieved ${tagInfos.length} tags from local repository`);
|
||||||
|
return tagInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillTagInformation(repositoryPath: string, owner: string, repo: string, tagInfo: TagInfo): Promise<TagInfo> {
|
||||||
|
return this.getTagByCreateTime(repositoryPath, tagInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDiffRemote(owner: string, repo: string, base: string, head: string): Promise<DiffInfo> {
|
||||||
|
core.info(`ℹ️ Getting diff information from local repository in offline mode`);
|
||||||
|
const gitHelper = await createCommandManager(this.repositoryPath);
|
||||||
|
|
||||||
|
// Get diff stats
|
||||||
|
const diffStats = await gitHelper.getDiffStats(base, head);
|
||||||
|
|
||||||
|
// Get commits
|
||||||
|
const commitInfo = await gitHelper.getCommitsBetween(base, head);
|
||||||
|
|
||||||
|
return {
|
||||||
|
changedFiles: diffStats.changedFiles,
|
||||||
|
additions: diffStats.additions,
|
||||||
|
deletions: diffStats.deletions,
|
||||||
|
changes: diffStats.changes,
|
||||||
|
commits: commitInfo.count,
|
||||||
|
commitInfo: commitInfo.commits.map(commit => ({
|
||||||
|
sha: commit.sha,
|
||||||
|
summary: commit.subject.split('\n')[0],
|
||||||
|
message: commit.message,
|
||||||
|
author: commit.author,
|
||||||
|
authorName: commit.authorName,
|
||||||
|
authorDate: moment(commit.authorDate),
|
||||||
|
committer: "",
|
||||||
|
committerName: "",
|
||||||
|
commitDate: moment(commit.authorDate),
|
||||||
|
prNumber: undefined
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async getForCommitHash(owner: string, repo: string, commit_sha: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
|
core.info(`⚠️ getForCommitHash not supported in offline mode`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async getBetweenDates(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
owner: string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
repo: string,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
fromDate: moment.Moment,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
toDate: moment.Moment,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
maxPullRequests: number
|
||||||
|
): Promise<PullRequestInfo[]> {
|
||||||
|
core.info(`⚠️ getBetweenDates not supported in offline mode`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async getOpen(owner: string, repo: string, maxPullRequests: number): Promise<PullRequestInfo[]> {
|
||||||
|
core.info(`⚠️ getOpen not supported in offline mode`);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async getReviews(owner: string, repo: string, pr: PullRequestInfo): Promise<void> {
|
||||||
|
core.info(`⚠️ getReviews not supported in offline mode`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
"noImplicitThis": true,
|
"noImplicitThis": true,
|
||||||
"moduleResolution": "Node16",
|
"moduleResolution": "Node16",
|
||||||
"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'. */
|
||||||
|
"isolatedModules": true,
|
||||||
"lib": [ "ESNext","ES2021.String", "dom"] /* Enable custom `ES2021.String` extension in typescript for `replaceAll` */
|
"lib": [ "ESNext","ES2021.String", "dom"] /* Enable custom `ES2021.String` extension in typescript for `replaceAll` */
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "__tests__/*.ts", "**/*.test.ts", "**/**/*.test.ts"],
|
"exclude": ["node_modules", "__tests__/*.ts", "**/*.test.ts", "**/**/*.test.ts"],
|
||||||
|
|||||||
Reference in New Issue
Block a user