Skip to content

Commit aa7ffa5

Browse files
authored
Merge pull request #82 from jdcmarques/feat/add-target-dir-options
feat: add target_dir to action options
2 parents a1245bc + 65d1af0 commit aa7ffa5

File tree

7 files changed

+265
-3
lines changed

7 files changed

+265
-3
lines changed

README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,33 @@ jobs:
7373
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7474
```
7575

76+
77+
### When pushed to master, push the contents of `/public/site` to the `www` folder on the `gh-pages` branch on the same repo
78+
79+
```yml
80+
name: Deploy to GitHub Pages
81+
on:
82+
push:
83+
branches:
84+
- master
85+
86+
jobs:
87+
deploy:
88+
name: Deploy to GitHub Pages
89+
runs-on: ubuntu-latest
90+
steps:
91+
- uses: actions/checkout@master
92+
93+
- name: Deploy
94+
uses: s0/git-publish-subdir-action@develop
95+
env:
96+
REPO: self
97+
BRANCH: gh-pages
98+
FOLDER: public/site
99+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
100+
TARGET_DIR: www
101+
```
102+
76103
### When pushed to master, run a build step, then push `/build` to the `gh-pages` branch on another repo on GitHub
77104

78105
```yml
@@ -174,6 +201,7 @@ All configuration options are passed in via `env`, as environment variables.
174201
| `CLEAR_GLOBS_FILE` | An optional path to a file to use as a list of globs defining which files to delete when clearing the target branch. | No |
175202
| `COMMIT_NAME` | The username the autogenerated commit will use. If unset, uses the commit pusher's username. | No |
176203
| `COMMIT_EMAIL` | The email the autogenerated commit will use. If unset, uses the commit pusher's email. | No |
204+
| `TARGET_DIR` | An optional string to change the directory where the files are copied to. | No |
177205

178206

179207
### Custom commit messages
@@ -226,6 +254,13 @@ everything, and you will need to specify exactly what needs to be deleted.**
226254
!.git
227255
```
228256

257+
1. Default behaviour with a custom target directory:
258+
259+
```
260+
target_dir/**/*
261+
!.git
262+
```
263+
229264
1. Delete everything except the `.git` and `foobar` folder:
230265

231266
```
@@ -329,4 +364,4 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
329364
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
330365
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
331366
-----END OPENSSH PRIVATE KEY-----
332-
```
367+
```

action/dist/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12280,6 +12280,10 @@ const main = async ({ env = process.env, log, }) => {
1228012280
.filter((s) => s !== '');
1228112281
return globList;
1228212282
}
12283+
else if (env.TARGET_DIR) {
12284+
log.log(`##[info] Removing all files from target dir ${env.TARGET_DIR} on target branch`);
12285+
return [`${env.TARGET_DIR}/**/*`, '!.git'];
12286+
}
1228312287
else {
1228412288
// Remove all files
1228512289
log.log(`##[info] Removing all files from target branch`);
@@ -12297,9 +12301,16 @@ const main = async ({ env = process.env, log, }) => {
1229712301
await fs_1.promises.unlink(entry);
1229812302
}
1229912303
const folder = path.resolve(process.cwd(), config.folder);
12304+
const destinationFolder = env.TARGET_DIR ? env.TARGET_DIR : './';
12305+
// Make sure the destination folder exists
12306+
await (0, io_1.mkdirP)(path.resolve(REPO_TEMP, destinationFolder));
1230012307
log.log(`##[info] Copying all files from ${folder}`);
1230112308
// TODO: replace this copy with a node implementation
12302-
await (0, exports.exec)(`cp -rT "${folder}"/ ./`, { log, env: childEnv, cwd: REPO_TEMP });
12309+
await (0, exports.exec)(`cp -rT "${folder}"/ ${destinationFolder}`, {
12310+
log,
12311+
env: childEnv,
12312+
cwd: REPO_TEMP,
12313+
});
1230312314
await (0, exports.exec)(`git add -A .`, { log, env: childEnv, cwd: REPO_TEMP });
1230412315
const message = config.message
1230512316
.replace(/\{target\-branch\}/g, config.branch)

action/src/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ export interface EnvironmentVariables {
143143
GITHUB_EVENT_PATH?: string;
144144
/** The name of the person / app that that initiated the workflow */
145145
GITHUB_ACTOR?: string;
146+
/**
147+
* An optional string to change the directory where the files are copied to
148+
*/
149+
TARGET_DIR?: string;
146150
}
147151

148152
declare global {
@@ -547,6 +551,11 @@ export const main = async ({
547551
.map((s) => s.trim())
548552
.filter((s) => s !== '');
549553
return globList;
554+
} else if (env.TARGET_DIR) {
555+
log.log(
556+
`##[info] Removing all files from target dir ${env.TARGET_DIR} on target branch`
557+
);
558+
return [`${env.TARGET_DIR}/**/*`, '!.git'];
550559
} else {
551560
// Remove all files
552561
log.log(`##[info] Removing all files from target branch`);
@@ -564,9 +573,18 @@ export const main = async ({
564573
await fs.unlink(entry);
565574
}
566575
const folder = path.resolve(process.cwd(), config.folder);
576+
const destinationFolder = env.TARGET_DIR ? env.TARGET_DIR : './';
577+
578+
// Make sure the destination folder exists
579+
await mkdirP(path.resolve(REPO_TEMP, destinationFolder));
580+
567581
log.log(`##[info] Copying all files from ${folder}`);
568582
// TODO: replace this copy with a node implementation
569-
await exec(`cp -rT "${folder}"/ ./`, { log, env: childEnv, cwd: REPO_TEMP });
583+
await exec(`cp -rT "${folder}"/ ${destinationFolder}`, {
584+
log,
585+
env: childEnv,
586+
cwd: REPO_TEMP,
587+
});
570588
await exec(`git add -A .`, { log, env: childEnv, cwd: REPO_TEMP });
571589
const message = config.message
572590
.replace(/\{target\-branch\}/g, config.branch)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Deploy to a branch on a custom dir that exists 1`] = `
4+
"msg:Update master to output generated at <sha>
5+
tree:91548ed23fe65d56dfcbb58357a11c32c9b0b95d
6+
author:s0 <s0@users.noreply.github.com>
7+
msg:initial
8+
tree:6ceb2d248e9b9c62291e9d1a5c4afeca8a49b2c8
9+
author:Test User <test@example.com>"
10+
`;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`Deploy to a branch on a custom dir that does not exist 1`] = `
4+
"msg:Update master to output generated at <sha>
5+
tree:91548ed23fe65d56dfcbb58357a11c32c9b0b95d
6+
author:s0 <s0@users.noreply.github.com>
7+
msg:initial
8+
tree:2ba0f344a4227360745f8b743b28af58d010c2f4
9+
author:Test User <test@example.com>"
10+
`;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { promises as fs } from 'fs';
2+
import * as path from 'path';
3+
import { mkdirP } from '@actions/io';
4+
5+
import * as util from '../util';
6+
import { prepareTestFolders } from '../util/io';
7+
import { listTree } from '../util/git';
8+
9+
it('Deploy to a branch on a custom dir that exists', async () => {
10+
const folders = await prepareTestFolders({ __filename });
11+
12+
// Create empty repo
13+
await util.wrappedExec('git init --bare', { cwd: folders.repoDir });
14+
15+
// Clone repo, and create an initial commit
16+
await util.wrappedExec(`git clone "${folders.repoDir}" clone`, {
17+
cwd: folders.workDir,
18+
});
19+
await fs.writeFile(path.join(folders.repoCloneDir, 'initial1'), 'foobar1');
20+
await fs.writeFile(path.join(folders.repoCloneDir, 'initial2'), 'foobar2');
21+
await mkdirP(path.join(folders.repoCloneDir, 'folder'));
22+
await fs.writeFile(path.join(folders.repoCloneDir, 'folder', 'a'), 'foobar1');
23+
await fs.writeFile(path.join(folders.repoCloneDir, 'folder', 'b'), 'foobar2');
24+
await mkdirP(path.join(folders.repoCloneDir, 'custom', 'b'));
25+
await fs.writeFile(path.join(folders.repoCloneDir, 'custom', 'a'), 'foobar1');
26+
await fs.writeFile(
27+
path.join(folders.repoCloneDir, 'custom', 'b', 'c'),
28+
'foobar1'
29+
);
30+
await util.wrappedExec(`git add -A .`, { cwd: folders.repoCloneDir });
31+
await util.wrappedExec(`git config user.name "Test User"`, {
32+
cwd: folders.repoCloneDir,
33+
});
34+
await util.wrappedExec(`git config user.email "test@example.com"`, {
35+
cwd: folders.repoCloneDir,
36+
});
37+
await util.wrappedExec(`git commit -m initial`, {
38+
cwd: folders.repoCloneDir,
39+
});
40+
await util.wrappedExec(`git push origin master`, {
41+
cwd: folders.repoCloneDir,
42+
});
43+
44+
// Create dummy data
45+
await mkdirP(path.join(folders.dataDir, 'dummy'));
46+
await fs.writeFile(path.join(folders.dataDir, 'dummy', 'baz'), 'foobar');
47+
await fs.writeFile(path.join(folders.dataDir, 'dummy', '.bat'), 'foobar');
48+
49+
// Run Action
50+
await util.runWithGithubEnv(
51+
path.basename(__filename),
52+
{
53+
REPO: folders.repoUrl,
54+
BRANCH: 'master',
55+
FOLDER: folders.dataDir,
56+
SSH_PRIVATE_KEY: (await fs.readFile(util.SSH_PRIVATE_KEY)).toString(),
57+
KNOWN_HOSTS_FILE: util.KNOWN_HOSTS,
58+
TARGET_DIR: 'custom',
59+
},
60+
's0/test',
61+
{},
62+
's0'
63+
);
64+
65+
// Check that the list of files in the root of the target repo is as expected
66+
expect(await listTree(folders.repoDir)).toEqual([
67+
'.',
68+
'custom',
69+
'custom/dummy',
70+
'custom/dummy/.bat',
71+
'custom/dummy/baz',
72+
'folder',
73+
'folder/a',
74+
'folder/b',
75+
'initial1',
76+
'initial2',
77+
]);
78+
79+
// Check that the log of the repo is as expected
80+
// (check tree-hash, commit message, and author)
81+
const log = (
82+
await util.exec(
83+
'git log --pretty="format:msg:%s%ntree:%T%nauthor:%an <%ae>" master',
84+
{
85+
cwd: folders.repoDir,
86+
}
87+
)
88+
).stdout;
89+
const sha = await util.getRepoSha();
90+
const cleanedLog = log.replace(sha, '<sha>');
91+
expect(cleanedLog).toMatchSnapshot();
92+
});
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { promises as fs } from 'fs';
2+
import * as path from 'path';
3+
import { mkdirP } from '@actions/io';
4+
5+
import * as util from '../util';
6+
import { prepareTestFolders } from '../util/io';
7+
import { listTree } from '../util/git';
8+
9+
it('Deploy to a branch on a custom dir that does not exist', async () => {
10+
const folders = await prepareTestFolders({ __filename });
11+
12+
// Create empty repo
13+
await util.wrappedExec('git init --bare', { cwd: folders.repoDir });
14+
15+
// Clone repo, and create an initial commit
16+
await util.wrappedExec(`git clone "${folders.repoDir}" clone`, {
17+
cwd: folders.workDir,
18+
});
19+
await fs.writeFile(path.join(folders.repoCloneDir, 'initial1'), 'foobar1');
20+
await fs.writeFile(path.join(folders.repoCloneDir, 'initial2'), 'foobar2');
21+
await mkdirP(path.join(folders.repoCloneDir, 'folder'));
22+
await fs.writeFile(path.join(folders.repoCloneDir, 'folder', 'a'), 'foobar1');
23+
await fs.writeFile(path.join(folders.repoCloneDir, 'folder', 'b'), 'foobar2');
24+
await util.wrappedExec(`git add -A .`, { cwd: folders.repoCloneDir });
25+
await util.wrappedExec(`git config user.name "Test User"`, {
26+
cwd: folders.repoCloneDir,
27+
});
28+
await util.wrappedExec(`git config user.email "test@example.com"`, {
29+
cwd: folders.repoCloneDir,
30+
});
31+
await util.wrappedExec(`git commit -m initial`, {
32+
cwd: folders.repoCloneDir,
33+
});
34+
await util.wrappedExec(`git push origin master`, {
35+
cwd: folders.repoCloneDir,
36+
});
37+
38+
// Create dummy data
39+
await mkdirP(path.join(folders.dataDir, 'dummy'));
40+
await fs.writeFile(path.join(folders.dataDir, 'dummy', 'baz'), 'foobar');
41+
await fs.writeFile(path.join(folders.dataDir, 'dummy', '.bat'), 'foobar');
42+
43+
// Run Action
44+
await util.runWithGithubEnv(
45+
path.basename(__filename),
46+
{
47+
REPO: folders.repoUrl,
48+
BRANCH: 'master',
49+
FOLDER: folders.dataDir,
50+
SSH_PRIVATE_KEY: (await fs.readFile(util.SSH_PRIVATE_KEY)).toString(),
51+
KNOWN_HOSTS_FILE: util.KNOWN_HOSTS,
52+
TARGET_DIR: 'custom',
53+
},
54+
's0/test',
55+
{},
56+
's0'
57+
);
58+
59+
// Check that the list of files in the root of the target repo is as expected
60+
expect(await listTree(folders.repoDir)).toEqual([
61+
'.',
62+
'custom',
63+
'custom/dummy',
64+
'custom/dummy/.bat',
65+
'custom/dummy/baz',
66+
'folder',
67+
'folder/a',
68+
'folder/b',
69+
'initial1',
70+
'initial2',
71+
]);
72+
73+
// Check that the log of the repo is as expected
74+
// (check tree-hash, commit message, and author)
75+
const log = (
76+
await util.exec(
77+
'git log --pretty="format:msg:%s%ntree:%T%nauthor:%an <%ae>" master',
78+
{
79+
cwd: folders.repoDir,
80+
}
81+
)
82+
).stdout;
83+
const sha = await util.getRepoSha();
84+
const cleanedLog = log.replace(sha, '<sha>');
85+
expect(cleanedLog).toMatchSnapshot();
86+
});

0 commit comments

Comments
 (0)