Skip to content

Commit

Permalink
feat: Add support for remote GitHub repository + working directory (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
xakraz authored Oct 30, 2024
1 parent d7c67e1 commit 2c19408
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 26 deletions.
4 changes: 2 additions & 2 deletions __tests__/git.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('Git CLI', () => {

describe('git add', () => {
beforeEach(() => {
jest.spyOn(cwd, 'getWorkspace').mockReturnValue('/test-workspace')
jest.spyOn(cwd, 'getWorkspace').mockReturnValue('test-workspace/')
})

it('should ensure file paths are within curent working directory', async () => {
Expand All @@ -190,7 +190,7 @@ describe('Git CLI', () => {
await addFileChanges(['*.ts', '~/.bashrc'])
expect(execMock).toHaveBeenCalledWith(
'git',
['add', '--', '/test-workspace/*.ts', '/test-workspace/~/.bashrc'],
['add', '--', 'test-workspace/*.ts', 'test-workspace/~/.bashrc'],
expect.objectContaining({
listeners: { stdline: expect.anything(), errline: expect.anything() },
})
Expand Down
13 changes: 13 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,23 @@ inputs:
Directory containing files to be committed. Default: GitHub workspace directory (root of repository).
required: false
default: ''
workdir:
description: |
Directory where the action should run. Default: GitHub workspace directory (root of repository from where the GH Workflow is triggered).
required: false
default: ''
commit-message:
description: |
Commit message for the file changes.
required: false
owner:
description: |
GitHub repository owner (user or organization), defaults to the repo invoking the action.
required: false
repo:
description: |
GitHub repository name, defaults to the repo invoking the action.
required: false
branch-name:
description: |
Branch to commit to. Default: Workflow triggered branch.
Expand Down
61 changes: 50 additions & 11 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29989,6 +29989,7 @@ function execGit(args) {
const debugOutput = [];
const warningOutput = [];
const errorOutput = [];
core.debug('execGit() - args: ' + JSON.stringify(args));
yield (0, exec_1.exec)('git', args, {
silent: true,
ignoreReturnCode: true,
Expand Down Expand Up @@ -30033,8 +30034,15 @@ function pushCurrentBranch() {
}
function addFileChanges(globPatterns) {
return __awaiter(this, void 0, void 0, function* () {
const cwd = (0, cwd_1.getCwd)();
const workspace = (0, cwd_1.getWorkspace)();
const workspacePaths = globPatterns.map((p) => (0, node_path_1.join)(workspace, p));
const resolvedWorkspace = (0, node_path_1.resolve)(workspace);
core.debug('addFileChanges() - resolvedWorkspace: ' + JSON.stringify(resolvedWorkspace));
let workspacePaths = globPatterns;
if (resolvedWorkspace.includes(cwd)) {
core.notice('addFileChanges() - "workspace" is a subdirectory, updating globPatterns');
workspacePaths = globPatterns.map((p) => (0, node_path_1.join)((0, node_path_1.relative)(cwd, resolvedWorkspace), p));
}
yield execGit(['add', '--', ...workspacePaths]);
});
}
Expand Down Expand Up @@ -30381,45 +30389,68 @@ const core = __importStar(__nccwpck_require__(7484));
const graphql_1 = __nccwpck_require__(1422);
const repo_1 = __nccwpck_require__(1839);
const git_1 = __nccwpck_require__(1243);
const cwd_1 = __nccwpck_require__(9827);
const input_1 = __nccwpck_require__(7797);
const errors_1 = __nccwpck_require__(3916);
function run() {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f;
try {
core.info('Getting info from GH Worklfow context');
const { owner, repo, branch } = (0, repo_1.getContext)();
core.info('Setting variables according to inputs and context');
core.debug('* branch');
const inputBranch = (0, input_1.getInput)('branch-name');
if (inputBranch && inputBranch !== branch) {
yield (0, git_1.switchBranch)(inputBranch);
const selectedBranch = inputBranch ? inputBranch : branch;
core.debug('* owner');
const inputOwner = (0, input_1.getInput)('owner');
const selectedOwner = inputOwner ? inputOwner : owner;
core.debug('* repo');
const inputRepo = (0, input_1.getInput)('repo');
const selectedRepo = inputRepo ? inputRepo : repo;
if (selectedOwner == owner &&
selectedRepo == repo &&
selectedBranch !== branch) {
core.warning('Pushing local and current branch to remote before proceeding');
// Git commands
yield (0, git_1.switchBranch)(selectedBranch);
yield (0, git_1.pushCurrentBranch)();
}
const currentBranch = inputBranch ? inputBranch : branch;
const repository = yield core.group(`fetching repository info for owner: ${owner}, repo: ${repo}, branch: ${currentBranch}`, () => __awaiter(this, void 0, void 0, function* () {
const repository = yield core.group(`fetching repository info for owner: ${selectedOwner}, repo: ${selectedRepo}, branch: ${selectedBranch}`, () => __awaiter(this, void 0, void 0, function* () {
const startTime = Date.now();
const repositoryData = yield (0, graphql_1.getRepository)(owner, repo, currentBranch);
const repositoryData = yield (0, graphql_1.getRepository)(selectedOwner, selectedRepo, selectedBranch);
const endTime = Date.now();
core.debug(`time taken: ${(endTime - startTime).toString()} ms`);
return repositoryData;
}));
core.info('Checking remote branches');
if (!repository.ref) {
if (inputBranch && currentBranch == inputBranch) {
if (inputBranch) {
throw new errors_1.InputBranchNotFound(inputBranch);
}
else {
throw new errors_1.BranchNotFound(currentBranch);
throw new errors_1.BranchNotFound(branch);
}
}
core.info('Processing to create signed commit');
core.debug('Get last (current?) commit');
const currentCommit = (_b = (_a = repository.ref.target.history) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b[0];
if (!currentCommit) {
throw new errors_1.BranchCommitNotFound(repository.ref.name);
}
let createdCommit;
const filePaths = core.getMultilineInput('files');
if (filePaths.length <= 0) {
core.debug('skip file commit, empty files input');
core.notice('skip file commit, empty files input');
}
else {
core.debug(`proceed with file commit, input: ${JSON.stringify(filePaths)}`);
core.debug(`Proceed with file commit, input: ${JSON.stringify(filePaths)}`);
const workdir = (0, cwd_1.getWorkdir)();
const cwd = (0, cwd_1.getCwd)();
if (cwd !== workdir) {
core.notice('Changing working directory to Workdir: ' + workdir);
process.chdir(workdir);
}
yield (0, git_1.addFileChanges)(filePaths);
const fileChanges = yield (0, git_1.getFileChanges)();
const fileCount = ((_d = (_c = fileChanges.additions) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) +
Expand All @@ -30441,7 +30472,7 @@ function run() {
const startTime = Date.now();
const commitData = yield (0, graphql_1.createCommitOnBranch)(currentCommit, commitMessage, {
repositoryNameWithOwner: repository.nameWithOwner,
branchName: currentBranch,
branchName: selectedBranch,
}, fileChanges);
const endTime = Date.now();
core.debug(`time taken: ${(endTime - startTime).toString()} ms`);
Expand Down Expand Up @@ -30565,6 +30596,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getCwd = getCwd;
exports.getWorkspace = getWorkspace;
exports.getWorkdir = getWorkdir;
const core = __importStar(__nccwpck_require__(7484));
const input_1 = __nccwpck_require__(7797);
function getCwd() {
Expand All @@ -30579,6 +30611,13 @@ function getWorkspace() {
core.debug(`workspace: ${workspace}`);
return workspace;
}
function getWorkdir() {
const workdir = (0, input_1.getInput)('workdir', {
default: process.env.GITHUB_WORKSPACE,
});
core.debug(`workdir: ${workdir}`);
return workdir;
}


/***/ }),
Expand Down
21 changes: 18 additions & 3 deletions src/git.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import * as core from '@actions/core'
import { exec } from '@actions/exec'
import { join } from 'node:path'
import { join, relative, resolve } from 'node:path'
import {
FileChanges,
FileAddition,
FileDeletion,
} from '@octokit/graphql-schema'

import { getWorkspace } from './utils/cwd'
import { getCwd, getWorkspace } from './utils/cwd'

async function execGit(args: string[]) {
const debugOutput: string[] = []
const warningOutput: string[] = []
const errorOutput: string[] = []

core.debug('execGit() - args: ' + JSON.stringify(args))
await exec('git', args, {
silent: true,
ignoreReturnCode: true,
Expand Down Expand Up @@ -53,8 +54,22 @@ export async function pushCurrentBranch() {
}

export async function addFileChanges(globPatterns: string[]) {
const cwd = getCwd()
const workspace = getWorkspace()
const workspacePaths = globPatterns.map((p) => join(workspace, p))
const resolvedWorkspace = resolve(workspace)
core.debug(
'addFileChanges() - resolvedWorkspace: ' + JSON.stringify(resolvedWorkspace)
)

let workspacePaths = globPatterns
if (resolvedWorkspace.includes(cwd)) {
core.notice(
'addFileChanges() - "workspace" is a subdirectory, updating globPatterns'
)
workspacePaths = globPatterns.map((p) =>
join(relative(cwd, resolvedWorkspace), p)
)
}

await execGit(['add', '--', ...workspacePaths])
}
Expand Down
57 changes: 47 additions & 10 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
pushCurrentBranch,
switchBranch,
} from './git'
import { getCwd, getWorkdir } from './utils/cwd'
import { getInput } from './utils/input'
import {
NoFileChanges,
Expand All @@ -23,32 +24,61 @@ import {

export async function run(): Promise<void> {
try {
core.info('Getting info from GH Worklfow context')
const { owner, repo, branch } = getContext()

core.info('Setting variables according to inputs and context')
core.debug('* branch')
const inputBranch = getInput('branch-name')
if (inputBranch && inputBranch !== branch) {
await switchBranch(inputBranch)
const selectedBranch = inputBranch ? inputBranch : branch

core.debug('* owner')
const inputOwner = getInput('owner')
const selectedOwner = inputOwner ? inputOwner : owner

core.debug('* repo')
const inputRepo = getInput('repo')
const selectedRepo = inputRepo ? inputRepo : repo

if (
selectedOwner == owner &&
selectedRepo == repo &&
selectedBranch !== branch
) {
core.warning(
'Pushing local and current branch to remote before proceeding'
)
// Git commands
await switchBranch(selectedBranch)
await pushCurrentBranch()
}
const currentBranch = inputBranch ? inputBranch : branch

const repository = await core.group(
`fetching repository info for owner: ${owner}, repo: ${repo}, branch: ${currentBranch}`,
`fetching repository info for owner: ${selectedOwner}, repo: ${selectedRepo}, branch: ${selectedBranch}`,
async () => {
const startTime = Date.now()
const repositoryData = await getRepository(owner, repo, currentBranch)
const repositoryData = await getRepository(
selectedOwner,
selectedRepo,
selectedBranch
)
const endTime = Date.now()
core.debug(`time taken: ${(endTime - startTime).toString()} ms`)
return repositoryData
}
)

core.info('Checking remote branches')
if (!repository.ref) {
if (inputBranch && currentBranch == inputBranch) {
if (inputBranch) {
throw new InputBranchNotFound(inputBranch)
} else {
throw new BranchNotFound(currentBranch)
throw new BranchNotFound(branch)
}
}

core.info('Processing to create signed commit')
core.debug('Get last (current?) commit')
const currentCommit = repository.ref.target.history?.nodes?.[0]
if (!currentCommit) {
throw new BranchCommitNotFound(repository.ref.name)
Expand All @@ -57,12 +87,19 @@ export async function run(): Promise<void> {
let createdCommit: Commit | undefined
const filePaths = core.getMultilineInput('files')
if (filePaths.length <= 0) {
core.debug('skip file commit, empty files input')
core.notice('skip file commit, empty files input')
} else {
core.debug(
`proceed with file commit, input: ${JSON.stringify(filePaths)}`
`Proceed with file commit, input: ${JSON.stringify(filePaths)}`
)

const workdir = getWorkdir()
const cwd = getCwd()
if (cwd !== workdir) {
core.notice('Changing working directory to Workdir: ' + workdir)
process.chdir(workdir)
}

await addFileChanges(filePaths)
const fileChanges = await getFileChanges()
const fileCount =
Expand All @@ -89,7 +126,7 @@ export async function run(): Promise<void> {
commitMessage,
{
repositoryNameWithOwner: repository.nameWithOwner,
branchName: currentBranch,
branchName: selectedBranch,
},
fileChanges
)
Expand Down
8 changes: 8 additions & 0 deletions src/utils/cwd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ export function getWorkspace() {
core.debug(`workspace: ${workspace}`)
return workspace
}

export function getWorkdir() {
const workdir = getInput('workdir', {
default: process.env.GITHUB_WORKSPACE,
})
core.debug(`workdir: ${workdir}`)
return workdir
}

0 comments on commit 2c19408

Please sign in to comment.