Skip to content

Commit

Permalink
feat: allow templates to be executable files (#41)
Browse files Browse the repository at this point in the history
Allows you to `chmod +x` a template file, making it executable. Then
when templating the file, the resulting file will also be executable.
  • Loading branch information
btkostner authored Apr 17, 2024
1 parent c1fcd3b commit 16ed4e7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
11 changes: 9 additions & 2 deletions src/templates.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { existsSync } from "fs";
import { readFile, mkdtemp, rm } from "fs/promises";
import { readFile, mkdtemp, rm, stat } from "fs/promises";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { join, resolve } from "path";
import { tmpdir } from "os";
import { v4 as uuid } from "uuid";

import { Config } from "./config";
import { templateFiles } from "./templates";
Expand Down Expand Up @@ -86,4 +85,12 @@ This file will only be templated if the \`NO_MARKDOWN\` environment variable is
const fileExists = existsSync(path);
expect(fileExists).toBe(false);
});

it<LocalTestContext>("will use the same file permissions as the template", async (ctx) => {
await templateFiles(ctx.config);
const path = join(ctx.config.fullPath, "executable.sh");
const stats = await stat(path);

expect(stats.mode.toString(8)).toBe("100755");
});
});
7 changes: 6 additions & 1 deletion src/templates.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as core from "@actions/core";
import * as glob from "@actions/glob";
import { open, readFile, writeFile } from "fs/promises";
import { chmod, open, readFile, stat, writeFile } from "fs/promises";
import { dirname, join, relative } from "path";
import { mkdirP } from "@actions/io";

Expand All @@ -20,6 +20,7 @@ export async function templateFiles(config: Config): Promise<void> {
core.info(`Template ${relativePath}`);

try {
const templateStats = await stat(templatePath);
const templateData = await readFile(templatePath, "utf8");
const templateHandlebar = Handlebars.compile(templateData);
const fileData = templateHandlebar(config.templateVariables);
Expand All @@ -33,6 +34,10 @@ export async function templateFiles(config: Config): Promise<void> {
const io = await open(writePath, "a");
await io.close();
await writeFile(writePath, fileData);
await chmod(
writePath,
"0" + (templateStats.mode & parseInt("777", 8)).toString(8),
);

core.debug("File written.");
} catch (err) {
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/templates/executable.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env

echo "This is an executable script."

0 comments on commit 16ed4e7

Please sign in to comment.