Skip to content

Commit 8d4757f

Browse files
committed
Implement initial setup for GitHub Actions: Ensure necessary directories exist and copy setup files if not already present.
1 parent 6247f22 commit 8d4757f

File tree

7 files changed

+397
-120
lines changed

7 files changed

+397
-120
lines changed

build/cli/index.js

Lines changed: 141 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -46418,6 +46418,7 @@ const constants_1 = __nccwpck_require__(8593);
4641846418
const chalk_1 = __importDefault(__nccwpck_require__(7037));
4641946419
const boxen_1 = __importDefault(__nccwpck_require__(4506));
4642046420
const queue_utils_1 = __nccwpck_require__(9800);
46421+
const setup_files_1 = __nccwpck_require__(1666);
4642146422
async function mainRun(execution) {
4642246423
const results = [];
4642346424
await execution.setup();
@@ -46458,6 +46459,19 @@ async function mainRun(execution) {
4645846459
title: constants_1.TITLE,
4645946460
titleAlignment: 'center'
4646046461
}));
46462+
if (execution.isSingleAction && execution.singleAction.currentSingleAction === constants_1.ACTIONS.INITIAL_SETUP) {
46463+
const cwd = process.cwd();
46464+
(0, logger_1.logInfo)('📁 Ensuring .github and .github/workflows exist...');
46465+
(0, setup_files_1.ensureGitHubDirs)(cwd);
46466+
(0, logger_1.logInfo)('📋 Copying setup files from setup/ to .github/ (skipping existing)...');
46467+
const copied = (0, setup_files_1.copySetupFiles)(cwd);
46468+
if (copied > 0) {
46469+
(0, logger_1.logInfo)(`✅ Copied ${copied} file(s).`);
46470+
}
46471+
else {
46472+
(0, logger_1.logInfo)('ℹ️ No setup/ folder found or all files already exist; nothing to copy.');
46473+
}
46474+
}
4646146475
}
4646246476
try {
4646346477
if (execution.isSingleAction) {
@@ -46970,8 +46984,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
4697046984
const child_process_1 = __nccwpck_require__(2081);
4697146985
const commander_1 = __nccwpck_require__(4379);
4697246986
const dotenv = __importStar(__nccwpck_require__(2437));
46973-
const fs = __importStar(__nccwpck_require__(7147));
46974-
const path = __importStar(__nccwpck_require__(1017));
4697546987
const local_action_1 = __nccwpck_require__(7002);
4697646988
const issue_repository_1 = __nccwpck_require__(57);
4697746989
const constants_1 = __nccwpck_require__(8593);
@@ -47345,17 +47357,6 @@ program
4734547357
process.exit(1);
4734647358
}
4734747359
});
47348-
/** Paths (relative to repo root) that must exist for the GitHub Action setup. */
47349-
const GITHUB_SETUP_FILES = [
47350-
'.github/workflows/copilot_commit.yml',
47351-
'.github/workflows/copilot_issue_comment.yml',
47352-
'.github/workflows/copilot_issue.yml',
47353-
'.github/workflows/copilot_pull_request_comment.yml',
47354-
'.github/workflows/copilot_pull_request.yml',
47355-
'.github/workflows/hotfix_workflow.yml',
47356-
'.github/workflows/release_workflow.yml',
47357-
'.github/pull_request_template.md',
47358-
];
4735947360
/** Returns true if cwd is inside a git repository (work tree). */
4736047361
function isInsideGitRepo(cwd) {
4736147362
try {
@@ -47366,33 +47367,6 @@ function isInsideGitRepo(cwd) {
4736647367
return false;
4736747368
}
4736847369
}
47369-
/**
47370-
* Ensure .github and .github/workflows exist; create them if missing.
47371-
* @param cwd - Directory (repo root)
47372-
*/
47373-
function ensureGitHubDirs(cwd) {
47374-
const githubDir = path.join(cwd, '.github');
47375-
const workflowsDir = path.join(cwd, '.github', 'workflows');
47376-
if (!fs.existsSync(githubDir)) {
47377-
(0, logger_1.logInfo)('Creating .github/...');
47378-
fs.mkdirSync(githubDir, { recursive: true });
47379-
}
47380-
if (!fs.existsSync(workflowsDir)) {
47381-
(0, logger_1.logInfo)('Creating .github/workflows/...');
47382-
fs.mkdirSync(workflowsDir, { recursive: true });
47383-
}
47384-
}
47385-
/**
47386-
* Check if the directory contains the required .github/ setup files for the GitHub Action.
47387-
* @param cwd - Directory to check (e.g. process.cwd())
47388-
* @returns { ok: true } or { ok: false, missing: string[] }
47389-
*/
47390-
function checkGitHubSetupFiles(cwd) {
47391-
const missing = GITHUB_SETUP_FILES.filter((rel) => !fs.existsSync(path.join(cwd, rel)));
47392-
if (missing.length === 0)
47393-
return { ok: true };
47394-
return { ok: false, missing };
47395-
}
4739647370
/**
4739747371
* Run the initial setup to configure labels, issue types, and verify access.
4739847372
*/
@@ -47403,31 +47377,20 @@ program
4740347377
.option('-t, --token <token>', 'Personal access token', process.env.PERSONAL_ACCESS_TOKEN)
4740447378
.action(async (options) => {
4740547379
const cwd = process.cwd();
47406-
(0, logger_1.logInfo)('Checking we are inside a git repository...');
47380+
(0, logger_1.logInfo)('🔍 Checking we are inside a git repository...');
4740747381
if (!isInsideGitRepo(cwd)) {
47408-
(0, logger_1.logError)('Not a git repository. Run "copilot setup" from the root of a git repo.');
47409-
process.exit(1);
47410-
}
47411-
(0, logger_1.logInfo)('Git repository detected.');
47412-
(0, logger_1.logInfo)('Ensuring .github and .github/workflows exist...');
47413-
ensureGitHubDirs(cwd);
47414-
(0, logger_1.logInfo)('Checking GitHub Action setup files in .github/...');
47415-
const setupCheck = checkGitHubSetupFiles(cwd);
47416-
if (!setupCheck.ok) {
47417-
(0, logger_1.logError)('Setup requires the GitHub Action files in .github/. Missing:');
47418-
setupCheck.missing.forEach((f) => (0, logger_1.logError)(` - ${f}`));
47419-
(0, logger_1.logError)('Copy the contents of the setup/ folder (workflows, pull_request_template.md) into .github/ and run setup again.');
47382+
(0, logger_1.logError)('❌ Not a git repository. Run "copilot setup" from the root of a git repo.');
4742047383
process.exit(1);
4742147384
}
47422-
(0, logger_1.logInfo)('All required setup files present.');
47423-
(0, logger_1.logInfo)('Resolving repository (owner/repo)...');
47385+
(0, logger_1.logInfo)('✅ Git repository detected.');
47386+
(0, logger_1.logInfo)('🔗 Resolving repository (owner/repo)...');
4742447387
const gitInfo = getGitInfo();
4742547388
if ('error' in gitInfo) {
4742647389
(0, logger_1.logError)(gitInfo.error);
4742747390
process.exit(1);
4742847391
}
47429-
(0, logger_1.logInfo)(`Repository: ${gitInfo.owner}/${gitInfo.repo}`);
47430-
(0, logger_1.logInfo)('Running initial setup (labels, issue types, access)...');
47392+
(0, logger_1.logInfo)(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`);
47393+
(0, logger_1.logInfo)('⚙️ Running initial setup (labels, issue types, access)...');
4743147394
const params = {
4743247395
[constants_1.INPUT_KEYS.DEBUG]: options.debug.toString(),
4743347396
[constants_1.INPUT_KEYS.SINGLE_ACTION]: constants_1.ACTIONS.INITIAL_SETUP,
@@ -57964,6 +57927,127 @@ const waitForPreviousRuns = async (params) => {
5796457927
exports.waitForPreviousRuns = waitForPreviousRuns;
5796557928

5796657929

57930+
/***/ }),
57931+
57932+
/***/ 1666:
57933+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
57934+
57935+
"use strict";
57936+
57937+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
57938+
if (k2 === undefined) k2 = k;
57939+
var desc = Object.getOwnPropertyDescriptor(m, k);
57940+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
57941+
desc = { enumerable: true, get: function() { return m[k]; } };
57942+
}
57943+
Object.defineProperty(o, k2, desc);
57944+
}) : (function(o, m, k, k2) {
57945+
if (k2 === undefined) k2 = k;
57946+
o[k2] = m[k];
57947+
}));
57948+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
57949+
Object.defineProperty(o, "default", { enumerable: true, value: v });
57950+
}) : function(o, v) {
57951+
o["default"] = v;
57952+
});
57953+
var __importStar = (this && this.__importStar) || (function () {
57954+
var ownKeys = function(o) {
57955+
ownKeys = Object.getOwnPropertyNames || function (o) {
57956+
var ar = [];
57957+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
57958+
return ar;
57959+
};
57960+
return ownKeys(o);
57961+
};
57962+
return function (mod) {
57963+
if (mod && mod.__esModule) return mod;
57964+
var result = {};
57965+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
57966+
__setModuleDefault(result, mod);
57967+
return result;
57968+
};
57969+
})();
57970+
Object.defineProperty(exports, "__esModule", ({ value: true }));
57971+
exports.ensureGitHubDirs = ensureGitHubDirs;
57972+
exports.copySetupFiles = copySetupFiles;
57973+
const fs = __importStar(__nccwpck_require__(7147));
57974+
const path = __importStar(__nccwpck_require__(1017));
57975+
const logger_1 = __nccwpck_require__(8836);
57976+
/**
57977+
* Ensure .github and .github/workflows exist; create them if missing.
57978+
* @param cwd - Directory (repo root)
57979+
*/
57980+
function ensureGitHubDirs(cwd) {
57981+
const githubDir = path.join(cwd, '.github');
57982+
const workflowsDir = path.join(cwd, '.github', 'workflows');
57983+
if (!fs.existsSync(githubDir)) {
57984+
(0, logger_1.logInfo)('📁 Creating .github/...');
57985+
fs.mkdirSync(githubDir, { recursive: true });
57986+
}
57987+
if (!fs.existsSync(workflowsDir)) {
57988+
(0, logger_1.logInfo)('📁 Creating .github/workflows/...');
57989+
fs.mkdirSync(workflowsDir, { recursive: true });
57990+
}
57991+
}
57992+
/**
57993+
* Copy setup files from setup/ to repo (.github/ workflows, pull_request_template.md, .env at root).
57994+
* Skips files that already exist at destination (no overwrite).
57995+
* Logs each file copied or skipped. No-op if setup/ does not exist.
57996+
* @param cwd - Repo root
57997+
* @returns Number of files copied
57998+
*/
57999+
function copySetupFiles(cwd) {
58000+
const setupDir = path.join(cwd, 'setup');
58001+
if (!fs.existsSync(setupDir))
58002+
return 0;
58003+
let copied = 0;
58004+
const workflowsSrc = path.join(setupDir, 'workflows');
58005+
const workflowsDst = path.join(cwd, '.github', 'workflows');
58006+
if (fs.existsSync(workflowsSrc)) {
58007+
const files = fs.readdirSync(workflowsSrc).filter((f) => f.endsWith('.yml') || f.endsWith('.yaml'));
58008+
for (const f of files) {
58009+
const src = path.join(workflowsSrc, f);
58010+
const dst = path.join(workflowsDst, f);
58011+
if (fs.statSync(src).isFile()) {
58012+
if (fs.existsSync(dst)) {
58013+
(0, logger_1.logInfo)(` ⏭️ .github/workflows/${f} already exists; skipping.`);
58014+
}
58015+
else {
58016+
fs.copyFileSync(src, dst);
58017+
(0, logger_1.logInfo)(` ✅ Copied setup/workflows/${f} → .github/workflows/${f}`);
58018+
copied += 1;
58019+
}
58020+
}
58021+
}
58022+
}
58023+
const prTemplateSrc = path.join(setupDir, 'pull_request_template.md');
58024+
const prTemplateDst = path.join(cwd, '.github', 'pull_request_template.md');
58025+
if (fs.existsSync(prTemplateSrc)) {
58026+
if (fs.existsSync(prTemplateDst)) {
58027+
(0, logger_1.logInfo)(' ⏭️ .github/pull_request_template.md already exists; skipping.');
58028+
}
58029+
else {
58030+
fs.copyFileSync(prTemplateSrc, prTemplateDst);
58031+
(0, logger_1.logInfo)(' ✅ Copied setup/pull_request_template.md → .github/pull_request_template.md');
58032+
copied += 1;
58033+
}
58034+
}
58035+
const envSrc = path.join(setupDir, '.env');
58036+
const envDst = path.join(cwd, '.env');
58037+
if (fs.existsSync(envSrc) && fs.statSync(envSrc).isFile()) {
58038+
if (fs.existsSync(envDst)) {
58039+
(0, logger_1.logInfo)(' ⏭️ .env already exists; skipping.');
58040+
}
58041+
else {
58042+
fs.copyFileSync(envSrc, envDst);
58043+
(0, logger_1.logInfo)(' ✅ Copied setup/.env → .env');
58044+
copied += 1;
58045+
}
58046+
}
58047+
return copied;
58048+
}
58049+
58050+
5796758051
/***/ }),
5796858052

5796958053
/***/ 6676:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Ensure .github and .github/workflows exist; create them if missing.
3+
* @param cwd - Directory (repo root)
4+
*/
5+
export declare function ensureGitHubDirs(cwd: string): void;
6+
/**
7+
* Copy setup files from setup/ to repo (.github/ workflows, pull_request_template.md, .env at root).
8+
* Skips files that already exist at destination (no overwrite).
9+
* Logs each file copied or skipped. No-op if setup/ does not exist.
10+
* @param cwd - Repo root
11+
* @returns Number of files copied
12+
*/
13+
export declare function copySetupFiles(cwd: string): number;

0 commit comments

Comments
 (0)