@rindrics/initrepo 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/dist/cli.js +107 -11
- package/package.json +1 -1
- package/src/cli.ts +2 -0
- package/src/commands/setup-renovate.ts +138 -0
- package/src/templates/common/renovate.json5.ejs +14 -0
- /package/{renovate.json → renovate.json5} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.3.1](https://github.com/Rindrics/initrepo/compare/v0.3.0...v0.3.1) - 2026-01-19
|
|
4
|
+
- feat: add renovate command by @Rindrics in https://github.com/Rindrics/initrepo/pull/38
|
|
5
|
+
|
|
3
6
|
## [v0.3.0](https://github.com/Rindrics/initrepo/compare/v0.2.1...v0.3.0) - 2026-01-19
|
|
4
7
|
- ci: use renovate to use bun by @Rindrics in https://github.com/Rindrics/initrepo/pull/35
|
|
5
8
|
- feat: generate tagpr config by @Rindrics in https://github.com/Rindrics/initrepo/pull/37
|
package/dist/cli.js
CHANGED
|
@@ -4207,7 +4207,7 @@ var {
|
|
|
4207
4207
|
// package.json
|
|
4208
4208
|
var package_default = {
|
|
4209
4209
|
name: "@rindrics/initrepo",
|
|
4210
|
-
version: "0.3.
|
|
4210
|
+
version: "0.3.1",
|
|
4211
4211
|
description: "setup GitHub repo with dev tools",
|
|
4212
4212
|
type: "module",
|
|
4213
4213
|
bin: {
|
|
@@ -4363,6 +4363,21 @@ bun run build
|
|
|
4363
4363
|
exclude:
|
|
4364
4364
|
labels:
|
|
4365
4365
|
- tagpr
|
|
4366
|
+
`,
|
|
4367
|
+
"common/renovate.json5.ejs": `{
|
|
4368
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
4369
|
+
"extends": ["config:recommended"],
|
|
4370
|
+
"packageRules": [
|
|
4371
|
+
{
|
|
4372
|
+
"matchUpdateTypes": ["major", "minor", "patch"],
|
|
4373
|
+
"automerge": true
|
|
4374
|
+
}
|
|
4375
|
+
],
|
|
4376
|
+
"lockFileMaintenance": {
|
|
4377
|
+
"enabled": true,
|
|
4378
|
+
"schedule": ["before 5am on monday"]
|
|
4379
|
+
}
|
|
4380
|
+
}
|
|
4366
4381
|
`,
|
|
4367
4382
|
"common/workflows/publish.yml.ejs": `name: Publish to npm
|
|
4368
4383
|
|
|
@@ -11641,7 +11656,7 @@ function registerSetupHuskyCommand(program2) {
|
|
|
11641
11656
|
});
|
|
11642
11657
|
}
|
|
11643
11658
|
|
|
11644
|
-
// src/commands/setup-
|
|
11659
|
+
// src/commands/setup-renovate.ts
|
|
11645
11660
|
import * as fs4 from "node:fs/promises";
|
|
11646
11661
|
import * as path4 from "node:path";
|
|
11647
11662
|
async function fileExists2(filePath) {
|
|
@@ -11652,6 +11667,86 @@ async function fileExists2(filePath) {
|
|
|
11652
11667
|
return false;
|
|
11653
11668
|
}
|
|
11654
11669
|
}
|
|
11670
|
+
function generateRenovateSetup() {
|
|
11671
|
+
return [
|
|
11672
|
+
{
|
|
11673
|
+
path: "renovate.json5",
|
|
11674
|
+
content: loadTemplate("common/renovate.json5.ejs", {})
|
|
11675
|
+
}
|
|
11676
|
+
];
|
|
11677
|
+
}
|
|
11678
|
+
async function writeFiles2(targetDir, files, force) {
|
|
11679
|
+
const written = [];
|
|
11680
|
+
const skipped = [];
|
|
11681
|
+
for (const file of files) {
|
|
11682
|
+
const filePath = path4.join(targetDir, file.path);
|
|
11683
|
+
const fileDir = path4.dirname(filePath);
|
|
11684
|
+
if (!force && await fileExists2(filePath)) {
|
|
11685
|
+
skipped.push(file.path);
|
|
11686
|
+
continue;
|
|
11687
|
+
}
|
|
11688
|
+
await fs4.mkdir(fileDir, { recursive: true });
|
|
11689
|
+
await fs4.writeFile(filePath, file.content, "utf-8");
|
|
11690
|
+
written.push(file.path);
|
|
11691
|
+
}
|
|
11692
|
+
return { written, skipped };
|
|
11693
|
+
}
|
|
11694
|
+
async function setupRenovate(options) {
|
|
11695
|
+
const targetDir = options.targetDir ?? process.cwd();
|
|
11696
|
+
const force = options.force ?? false;
|
|
11697
|
+
const packageJsonPath = path4.join(targetDir, "package.json");
|
|
11698
|
+
if (!await fileExists2(packageJsonPath)) {
|
|
11699
|
+
throw new Error("package.json not found. Are you in a project directory?");
|
|
11700
|
+
}
|
|
11701
|
+
console.log(`\uD83D\uDD27 Setting up Renovate configuration...
|
|
11702
|
+
`);
|
|
11703
|
+
const files = generateRenovateSetup();
|
|
11704
|
+
const { written, skipped } = await writeFiles2(targetDir, files, force);
|
|
11705
|
+
if (written.length > 0) {
|
|
11706
|
+
console.log("✅ Created files:");
|
|
11707
|
+
for (const file of written) {
|
|
11708
|
+
console.log(` ${file}`);
|
|
11709
|
+
}
|
|
11710
|
+
}
|
|
11711
|
+
if (skipped.length > 0) {
|
|
11712
|
+
console.log(`
|
|
11713
|
+
⏭️ Skipped (already exist, use --force to overwrite):`);
|
|
11714
|
+
for (const file of skipped) {
|
|
11715
|
+
console.log(` ${file}`);
|
|
11716
|
+
}
|
|
11717
|
+
}
|
|
11718
|
+
console.log(`
|
|
11719
|
+
\uD83C\uDF89 Renovate setup complete!`);
|
|
11720
|
+
console.log(`
|
|
11721
|
+
\uD83D\uDCCB Next steps:`);
|
|
11722
|
+
console.log(" 1. Install Renovate GitHub App: https://github.com/apps/renovate");
|
|
11723
|
+
console.log(" 2. Grant access to this repository");
|
|
11724
|
+
}
|
|
11725
|
+
function registerSetupRenovateCommand(program2) {
|
|
11726
|
+
program2.command("setup-renovate").description("Set up Renovate configuration in an existing project").option("-t, --target-dir <path>", "Target directory (defaults to current directory)").option("-f, --force", "Overwrite existing files").action(async (opts) => {
|
|
11727
|
+
try {
|
|
11728
|
+
await setupRenovate({
|
|
11729
|
+
targetDir: opts.targetDir,
|
|
11730
|
+
force: opts.force
|
|
11731
|
+
});
|
|
11732
|
+
} catch (error) {
|
|
11733
|
+
console.error(`❌ Failed to setup Renovate: ${error instanceof Error ? error.message : String(error)}`);
|
|
11734
|
+
process.exit(1);
|
|
11735
|
+
}
|
|
11736
|
+
});
|
|
11737
|
+
}
|
|
11738
|
+
|
|
11739
|
+
// src/commands/setup-tagpr.ts
|
|
11740
|
+
import * as fs5 from "node:fs/promises";
|
|
11741
|
+
import * as path5 from "node:path";
|
|
11742
|
+
async function fileExists3(filePath) {
|
|
11743
|
+
try {
|
|
11744
|
+
await fs5.access(filePath);
|
|
11745
|
+
return true;
|
|
11746
|
+
} catch {
|
|
11747
|
+
return false;
|
|
11748
|
+
}
|
|
11749
|
+
}
|
|
11655
11750
|
async function generateTagprSetup() {
|
|
11656
11751
|
const actionVersions = await getLatestActionVersions();
|
|
11657
11752
|
return [
|
|
@@ -11668,18 +11763,18 @@ async function generateTagprSetup() {
|
|
|
11668
11763
|
}
|
|
11669
11764
|
];
|
|
11670
11765
|
}
|
|
11671
|
-
async function
|
|
11766
|
+
async function writeFiles3(targetDir, files, force) {
|
|
11672
11767
|
const written = [];
|
|
11673
11768
|
const skipped = [];
|
|
11674
11769
|
for (const file of files) {
|
|
11675
|
-
const filePath =
|
|
11676
|
-
const fileDir =
|
|
11677
|
-
if (!force && await
|
|
11770
|
+
const filePath = path5.join(targetDir, file.path);
|
|
11771
|
+
const fileDir = path5.dirname(filePath);
|
|
11772
|
+
if (!force && await fileExists3(filePath)) {
|
|
11678
11773
|
skipped.push(file.path);
|
|
11679
11774
|
continue;
|
|
11680
11775
|
}
|
|
11681
|
-
await
|
|
11682
|
-
await
|
|
11776
|
+
await fs5.mkdir(fileDir, { recursive: true });
|
|
11777
|
+
await fs5.writeFile(filePath, file.content, "utf-8");
|
|
11683
11778
|
written.push(file.path);
|
|
11684
11779
|
}
|
|
11685
11780
|
return { written, skipped };
|
|
@@ -11687,14 +11782,14 @@ async function writeFiles2(targetDir, files, force) {
|
|
|
11687
11782
|
async function setupTagpr(options) {
|
|
11688
11783
|
const targetDir = options.targetDir ?? process.cwd();
|
|
11689
11784
|
const force = options.force ?? false;
|
|
11690
|
-
const packageJsonPath =
|
|
11691
|
-
if (!await
|
|
11785
|
+
const packageJsonPath = path5.join(targetDir, "package.json");
|
|
11786
|
+
if (!await fileExists3(packageJsonPath)) {
|
|
11692
11787
|
throw new Error("package.json not found. Are you in a project directory?");
|
|
11693
11788
|
}
|
|
11694
11789
|
console.log(`\uD83D\uDD27 Setting up tagpr configuration...
|
|
11695
11790
|
`);
|
|
11696
11791
|
const files = await generateTagprSetup();
|
|
11697
|
-
const { written, skipped } = await
|
|
11792
|
+
const { written, skipped } = await writeFiles3(targetDir, files, force);
|
|
11698
11793
|
if (written.length > 0) {
|
|
11699
11794
|
console.log("✅ Created files:");
|
|
11700
11795
|
for (const file of written) {
|
|
@@ -11738,6 +11833,7 @@ function createProgram() {
|
|
|
11738
11833
|
registerInitCommand(program2);
|
|
11739
11834
|
registerPrepareReleaseCommand(program2);
|
|
11740
11835
|
registerSetupHuskyCommand(program2);
|
|
11836
|
+
registerSetupRenovateCommand(program2);
|
|
11741
11837
|
registerSetupTagprCommand(program2);
|
|
11742
11838
|
return program2;
|
|
11743
11839
|
}
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -4,6 +4,7 @@ import packageJson from '../package.json';
|
|
|
4
4
|
import { registerInitCommand } from './commands/init';
|
|
5
5
|
import { registerPrepareReleaseCommand } from './commands/prepare-release';
|
|
6
6
|
import { registerSetupHuskyCommand } from './commands/setup-husky';
|
|
7
|
+
import { registerSetupRenovateCommand } from './commands/setup-renovate';
|
|
7
8
|
import { registerSetupTagprCommand } from './commands/setup-tagpr';
|
|
8
9
|
|
|
9
10
|
const { version: VERSION, name: NAME } = packageJson;
|
|
@@ -19,6 +20,7 @@ export function createProgram(): Command {
|
|
|
19
20
|
registerInitCommand(program);
|
|
20
21
|
registerPrepareReleaseCommand(program);
|
|
21
22
|
registerSetupHuskyCommand(program);
|
|
23
|
+
registerSetupRenovateCommand(program);
|
|
22
24
|
registerSetupTagprCommand(program);
|
|
23
25
|
|
|
24
26
|
return program;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import type { Command } from 'commander';
|
|
4
|
+
import type { GeneratedFile } from '../generators/project';
|
|
5
|
+
import { loadTemplate } from '../generators/project';
|
|
6
|
+
|
|
7
|
+
export interface SetupRenovateOptions {
|
|
8
|
+
/** Target directory (defaults to current directory) */
|
|
9
|
+
targetDir?: string;
|
|
10
|
+
/** Force overwrite existing files */
|
|
11
|
+
force?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if file exists
|
|
16
|
+
*/
|
|
17
|
+
async function fileExists(filePath: string): Promise<boolean> {
|
|
18
|
+
try {
|
|
19
|
+
await fs.access(filePath);
|
|
20
|
+
return true;
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Generate renovate configuration
|
|
28
|
+
*/
|
|
29
|
+
function generateRenovateSetup(): GeneratedFile[] {
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
path: 'renovate.json5',
|
|
33
|
+
content: loadTemplate('common/renovate.json5.ejs', {}),
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Write generated files to target directory
|
|
40
|
+
*/
|
|
41
|
+
async function writeFiles(
|
|
42
|
+
targetDir: string,
|
|
43
|
+
files: GeneratedFile[],
|
|
44
|
+
force: boolean,
|
|
45
|
+
): Promise<{ written: string[]; skipped: string[] }> {
|
|
46
|
+
const written: string[] = [];
|
|
47
|
+
const skipped: string[] = [];
|
|
48
|
+
|
|
49
|
+
for (const file of files) {
|
|
50
|
+
const filePath = path.join(targetDir, file.path);
|
|
51
|
+
const fileDir = path.dirname(filePath);
|
|
52
|
+
|
|
53
|
+
// Check if file exists
|
|
54
|
+
if (!force && (await fileExists(filePath))) {
|
|
55
|
+
skipped.push(file.path);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Create directory if needed
|
|
60
|
+
await fs.mkdir(fileDir, { recursive: true });
|
|
61
|
+
|
|
62
|
+
// Write file
|
|
63
|
+
await fs.writeFile(filePath, file.content, 'utf-8');
|
|
64
|
+
written.push(file.path);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { written, skipped };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Main setup-renovate logic
|
|
72
|
+
*/
|
|
73
|
+
export async function setupRenovate(
|
|
74
|
+
options: SetupRenovateOptions,
|
|
75
|
+
): Promise<void> {
|
|
76
|
+
const targetDir = options.targetDir ?? process.cwd();
|
|
77
|
+
const force = options.force ?? false;
|
|
78
|
+
|
|
79
|
+
// Check if package.json exists
|
|
80
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
81
|
+
if (!(await fileExists(packageJsonPath))) {
|
|
82
|
+
throw new Error('package.json not found. Are you in a project directory?');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('🔧 Setting up Renovate configuration...\n');
|
|
86
|
+
|
|
87
|
+
// Generate renovate files
|
|
88
|
+
const files = generateRenovateSetup();
|
|
89
|
+
|
|
90
|
+
// Write files
|
|
91
|
+
const { written, skipped } = await writeFiles(targetDir, files, force);
|
|
92
|
+
|
|
93
|
+
// Report results
|
|
94
|
+
if (written.length > 0) {
|
|
95
|
+
console.log('✅ Created files:');
|
|
96
|
+
for (const file of written) {
|
|
97
|
+
console.log(` ${file}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (skipped.length > 0) {
|
|
102
|
+
console.log('\n⏭️ Skipped (already exist, use --force to overwrite):');
|
|
103
|
+
for (const file of skipped) {
|
|
104
|
+
console.log(` ${file}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log('\n🎉 Renovate setup complete!');
|
|
109
|
+
console.log('\n📋 Next steps:');
|
|
110
|
+
console.log(
|
|
111
|
+
' 1. Install Renovate GitHub App: https://github.com/apps/renovate',
|
|
112
|
+
);
|
|
113
|
+
console.log(' 2. Grant access to this repository');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function registerSetupRenovateCommand(program: Command): void {
|
|
117
|
+
program
|
|
118
|
+
.command('setup-renovate')
|
|
119
|
+
.description('Set up Renovate configuration in an existing project')
|
|
120
|
+
.option(
|
|
121
|
+
'-t, --target-dir <path>',
|
|
122
|
+
'Target directory (defaults to current directory)',
|
|
123
|
+
)
|
|
124
|
+
.option('-f, --force', 'Overwrite existing files')
|
|
125
|
+
.action(async (opts: { targetDir?: string; force?: boolean }) => {
|
|
126
|
+
try {
|
|
127
|
+
await setupRenovate({
|
|
128
|
+
targetDir: opts.targetDir,
|
|
129
|
+
force: opts.force,
|
|
130
|
+
});
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error(
|
|
133
|
+
`❌ Failed to setup Renovate: ${error instanceof Error ? error.message : String(error)}`,
|
|
134
|
+
);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
3
|
+
"extends": ["config:recommended"],
|
|
4
|
+
"packageRules": [
|
|
5
|
+
{
|
|
6
|
+
"matchUpdateTypes": ["major", "minor", "patch"],
|
|
7
|
+
"automerge": true
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"lockFileMaintenance": {
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"schedule": ["before 5am on monday"]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
File without changes
|