Compare commits

..

1 Commits

Author SHA1 Message Date
renovate-bot e4b42836fb chore(deps): update dependencies (non-major)
renovate/stability-days Updates have met minimum release age requirement
CI / Test (pull_request) Successful in 18s
CI / Check Dist (pull_request) Successful in 13s
CI / Dry-Run (pull_request) Successful in 12s
CI / Dry-Run Prerelease (pull_request) Successful in 13s
2026-05-16 10:02:07 +00:00
14 changed files with 4585 additions and 2332 deletions
-7
View File
@@ -1,7 +0,0 @@
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
+2 -2
View File
@@ -17,10 +17,10 @@ jobs:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: .nvmrc
- run: npm ci
+9 -9
View File
@@ -8,13 +8,13 @@ jobs:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: .nvmrc
- run: npm ci
- name: Format code
run: npm run format:check
run: npm run format
- name: Typecheck
run: npm run typecheck
- name: Run test
@@ -24,8 +24,8 @@ jobs:
name: Check Dist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: .nvmrc
- run: npm ci
@@ -43,10 +43,10 @@ jobs:
name: Dry-Run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: .nvmrc
- run: npm ci
@@ -68,10 +68,10 @@ jobs:
name: Dry-Run Prerelease
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version-file: .nvmrc
- run: npm ci
-1
View File
@@ -1 +0,0 @@
min-release-age=7
+8
View File
@@ -0,0 +1,8 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": false,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false
}
+90 -47
View File
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
roots: ["<rootDir>/src"],
testMatch: ["**/*.spec.ts"],
transform: {
"^.+\\.ts$": "ts-jest",
},
moduleFileExtensions: ["ts", "js", "json"],
};
-6
View File
@@ -1,6 +0,0 @@
import { defineConfig } from "oxfmt";
export default defineConfig({
// Most configuration is read from .editorconfig
ignorePatterns: ["node_modules/**", "dist/**"],
});
+4418 -2186
View File
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -1,27 +1,27 @@
{
"name": "conventional-semantic-git-tag-increment",
"description": "GitHub Action to increment semantic version tag based on conventional commits",
"license": "MIT",
"author": "Timo Behrendt <t.behrendt@t00n.de>",
"main": "src/index.ts",
"scripts": {
"typecheck": "tsc --noEmit",
"build": "rolldown -c",
"test": "vitest",
"format": "oxfmt",
"format:check": "oxfmt --check"
},
"dependencies": {
"@actions/core": "3.0.1",
"conventional-commits-parser": "3.2.4"
"build": "esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --target=node24 --minify",
"test": "jest",
"format": "prettier --write src/**/*.ts"
},
"author": "Timo Behrendt <t.behrendt@t00n.de>",
"license": "MIT",
"devDependencies": {
"@types/conventional-commits-parser": "5.0.2",
"@types/node": "24.13.2",
"@vitest/coverage-v8": "4.1.10",
"oxfmt": "0.59.0",
"rolldown": "1.2.0",
"typescript": "7.0.2",
"vitest": "4.1.10"
"@types/jest": "30.0.0",
"@types/node": "24.12.3",
"esbuild": "0.28.0",
"jest": "30.4.2",
"prettier": "3.8.3",
"ts-jest": "29.4.9",
"typescript": "5.9.3"
},
"dependencies": {
"@actions/core": "2.0.3",
"conventional-commits-parser": "3.2.4"
}
}
-12
View File
@@ -1,12 +0,0 @@
import { defineConfig } from "rolldown/config";
export default defineConfig({
input: "src/index.ts",
output: {
file: "dist/index.js",
format: "esm",
minify: true,
},
platform: "node",
treeshake: true,
});
+23 -21
View File
@@ -1,30 +1,28 @@
import { afterEach, beforeEach, describe, expect, it, vi, type MockedFunction } from "vitest";
import {
ConventionalCommitAnalyzer,
CoreService,
GitService,
IncrementType,
LocalCoreService,
LocalGitService,
Tag,
TagIncrementer,
GitService,
CoreService,
ConventionalCommitAnalyzer,
TagService,
TagIncrementer,
LocalGitService,
LocalCoreService,
} from "./main";
// Mock child_process.execSync
vi.mock("child_process", () => ({
execSync: vi.fn(),
jest.mock("child_process", () => ({
execSync: jest.fn(),
}));
import { execSync } from "child_process";
const mockExecSync = execSync as MockedFunction<typeof execSync>;
const mockExecSync = execSync as jest.MockedFunction<typeof execSync>;
// Mock interfaces for testing
class MockGitService implements GitService {
constructor(
private mockTags: { name: string }[] = [],
private mockCommit: { commit: { message: string } } = { commit: { message: "test commit" } },
private mockCommit: { commit: { message: string } } = { commit: { message: "test commit" } }
) {}
async listTags(perPage: number): Promise<{ name: string }[]> {
@@ -176,19 +174,19 @@ describe("TagService", () => {
it("should throw error for invalid format", () => {
expect(() => tagService.parseTag("invalid")).toThrow(
"Invalid tag format: invalid. Expected semantic version (e.g., 1.2.3)",
"Invalid tag format: invalid. Expected semantic version (e.g., 1.2.3)"
);
});
it("should throw error for non-numeric versions", () => {
expect(() => tagService.parseTag("1.a.3")).toThrow(
"Invalid tag format: 1.a.3. Expected semantic version (e.g., 1.2.3)",
"Invalid tag format: 1.a.3. Expected semantic version (e.g., 1.2.3)"
);
});
it("should throw error for incomplete version", () => {
expect(() => tagService.parseTag("1.2")).toThrow(
"Invalid tag format: 1.2. Expected semantic version (e.g., 1.2.3)",
"Invalid tag format: 1.2. Expected semantic version (e.g., 1.2.3)"
);
});
});
@@ -211,7 +209,7 @@ describe("TagIncrementer", () => {
mockGitService,
mockCoreService,
mockCommitAnalyzer,
mockTagService,
mockTagService
);
});
@@ -243,7 +241,7 @@ describe("TagIncrementer", () => {
expect(result).toBe("0.0.0");
expect(mockCoreService.getWarnings()).toContain(
"WARNING: No tags found in repository, defaulting to 0.0.0",
"WARNING: No tags found in repository, defaulting to 0.0.0"
);
});
@@ -271,7 +269,7 @@ describe("TagIncrementer", () => {
expect(result).toBe("0.0.0");
expect(mockCoreService.getWarnings()).toContain(
"WARNING: No real tags found (only pre-release tags), defaulting to 0.0.0",
"WARNING: No real tags found (only pre-release tags), defaulting to 0.0.0"
);
});
});
@@ -428,7 +426,7 @@ describe("LocalGitService", () => {
});
await expect(localGitService.testConnection()).rejects.toThrow(
"Not in a git repository. Please ensure this action runs after checkout.",
"Not in a git repository. Please ensure this action runs after checkout."
);
});
});
@@ -441,6 +439,10 @@ describe("LocalCoreService", () => {
localCoreService = new LocalCoreService();
});
// Note: These tests would require mocking the @actions/core module
// In a real implementation, you might want to use jest.mock() to mock the entire module
// For now, we'll just test that the methods exist and can be called
it("should have all required methods", () => {
expect(typeof localCoreService.getInput).toBe("function");
expect(typeof localCoreService.info).toBe("function");
@@ -457,7 +459,7 @@ describe("TagIncrementer Integration", () => {
[{ name: "v2.0.0-rc-26035c6e13" }, { name: "v1.1.4-rc-aa512edb16" }, { name: "v1.2.3" }],
{
commit: { message: "feat: new feature" },
},
}
);
const mockCoreService = new MockCoreService();
const commitAnalyzer = new ConventionalCommitAnalyzer();
@@ -467,7 +469,7 @@ describe("TagIncrementer Integration", () => {
mockGitService,
mockCoreService,
commitAnalyzer,
tagService,
tagService
);
const result = await tagIncrementer.incrementTag(undefined, "ref");
+9 -9
View File
@@ -100,7 +100,7 @@ export class TagIncrementer {
private gitService: GitService,
private coreService: CoreService,
private commitAnalyzer: ConventionalCommitAnalyzer,
private tagService: TagService,
private tagService: TagService
) {}
async getBaseTag(lastTag: string | undefined, maxTags: number = 50): Promise<string> {
@@ -138,7 +138,7 @@ export class TagIncrementer {
const analyzedCommit = this.commitAnalyzer.analyzeCommit(commit.message);
this.coreService.info(
`Analyzed commit - type: ${analyzedCommit.type}, breaking: ${analyzedCommit.breaking}`,
`Analyzed commit - type: ${analyzedCommit.type}, breaking: ${analyzedCommit.breaking}`
);
const incrementType = this.commitAnalyzer.determineIncrementType(analyzedCommit);
@@ -147,14 +147,14 @@ export class TagIncrementer {
return incrementType;
} catch (error) {
this.coreService.info(
`Error fetching commit ${ref}: ${error instanceof Error ? error.message : String(error)}`,
`Error fetching commit ${ref}: ${error instanceof Error ? error.message : String(error)}`
);
// Additional debugging for commit-related errors
if (error instanceof Error && error.message.includes("404")) {
this.coreService.info(`404 error suggests commit ${ref} was not found in repository`);
this.coreService.info(
`This could indicate: 1) SHA doesn't exist, 2) Repository access issue, 3) API endpoint mismatch`,
`This could indicate: 1) SHA doesn't exist, 2) Repository access issue, 3) API endpoint mismatch`
);
}
@@ -167,7 +167,7 @@ export class TagIncrementer {
ref: string,
maxTags: number = 50,
prerelease: boolean = false,
githubSha: string = "",
githubSha: string = ""
): Promise<string> {
this.coreService.info(`Starting tag increment process at ref ${ref}`);
@@ -175,7 +175,7 @@ export class TagIncrementer {
const parsedTag = this.tagService.parseTag(baseTag);
this.coreService.info(
`Parsed version: ${parsedTag.major}.${parsedTag.minor}.${parsedTag.patch}`,
`Parsed version: ${parsedTag.major}.${parsedTag.minor}.${parsedTag.patch}`
);
const incrementType = await this.determineIncrementType(ref);
@@ -187,7 +187,7 @@ export class TagIncrementer {
this.coreService.info(`New tag: ${renderedTag}`);
this.coreService.info(
`Successfully determined new tag: ${renderedTag} (${incrementType} increment)`,
`Successfully determined new tag: ${renderedTag} (${incrementType} increment)`
);
return renderedTag;
@@ -215,7 +215,7 @@ export class LocalGitService implements GitService {
return { commit: { message } };
} catch (error) {
throw new Error(
`Failed to get commit ${ref}: ${error instanceof Error ? error.message : String(error)}`,
`Failed to get commit ${ref}: ${error instanceof Error ? error.message : String(error)}`
);
}
}
@@ -296,7 +296,7 @@ export async function run(): Promise<void> {
ref,
maxTags,
prerelease,
githubSha,
githubSha
);
coreService.info(`Process completed successfully. New tag: ${newTag}`);
-16
View File
@@ -1,16 +0,0 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "node",
include: ["src/**/*.{spec,test}.ts"],
coverage: {
enabled: true,
provider: "v8",
include: ["src/**/*.ts"],
exclude: ["src/**/*.{spec,test}.ts"],
reporter: ["lcov"],
reportsDirectory: "coverage",
},
},
});