Skip to content

Commit

Permalink
Merge pull request #98 from noymer/skip_dependency_installation
Browse files Browse the repository at this point in the history
add option to skip dependency installation [#77 reopen]
  • Loading branch information
dscho committed Jan 4, 2022
2 parents b926bc4 + fa7a79e commit f309efd
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 68 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ You can then [manually run a workflow](https://docs.github.com/en/actions/managi

## Without sudo

By default we run the commands using sudo. If you get `sudo: not found` you can use the parameter below to execute the commands directly.
By default we run installation commands using sudo on Linux. If you get `sudo: not found` you can use the parameter below to execute the commands directly.

```yaml
name: CI
Expand Down Expand Up @@ -165,6 +165,22 @@ jobs:
tmate-server-ed25519-fingerprint: SHA256:jfttvoypkHiQYUqUCwKeqd9d1fJj/ZiQlFOHVl6E9sI
```

## Skip installing tmate

By default, tmate and its dependencies are installed in a platform-dependent manner. When using self-hosted agents, this can become unnecessary or can even break. You can skip installing tmate and its dependencies using `install-dependencies`:

```yaml
name: CI
on: [push]
jobs:
build:
runs-on: [self-hosted, linux]
steps:
- uses: mxschmitt/action-tmate@v3
with:
install-dependencies: false
```

## Continue a workflow

If you want to continue a workflow and you are inside a tmate session, just create a empty file with the name `continue` either in the root directory or in the project directory by running `touch continue` or `sudo touch /continue`.
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ inputs:
description: 'If apt should be executed with sudo or without'
required: false
default: 'true'
install-dependencies:
description: 'Whether or not to install dependencies for tmate on linux (openssh-client, xz-utils)'
required: false
default: 'true'
limit-access-to-actor:
description: 'If only the public SSH keys of the user triggering the workflow should be authorized'
required: false
Expand Down
64 changes: 33 additions & 31 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10334,44 +10334,46 @@ const TMATE_ARCH_MAP = {
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

async function run() {
const optionalSudoPrefix = core.getInput('sudo') === "true" ? "sudo " : "";
try {
core.debug("Installing dependencies")
let tmateExecutable = "tmate"
if (process.platform === "darwin") {
await execShellCommand('brew install tmate');
} else if (process.platform === "win32") {
await execShellCommand('pacman -Sy --noconfirm tmate');
tmateExecutable = 'CHERE_INVOKING=1 tmate'
} else {
const distro = await getLinuxDistro();
core.debug("linux distro: [" + distro + "]");
if (distro === "alpine") {
// for set -e workaround, we need to install bash because alpine doesn't have it
await execShellCommand(optionalSudoPrefix + 'apk add openssh-client xz bash');
if (core.getInput("install-dependencies") !== "false") {
core.debug("Installing dependencies")
if (process.platform === "darwin") {
await execShellCommand('brew install tmate');
} else if (process.platform === "win32") {
await execShellCommand('pacman -Sy --noconfirm tmate');
} else {
await execShellCommand(optionalSudoPrefix + 'apt-get update');
await execShellCommand(optionalSudoPrefix + 'apt-get install -y openssh-client xz-utils');
}
const optionalSudoPrefix = core.getInput("sudo") === "true" ? "sudo " : "";
const distro = await getLinuxDistro();
core.debug("linux distro: [" + distro + "]");
if (distro === "alpine") {
// for set -e workaround, we need to install bash because alpine doesn't have it
await execShellCommand(optionalSudoPrefix + 'apk add openssh-client xz bash');
} else {
await execShellCommand(optionalSudoPrefix + 'apt-get update');
await execShellCommand(optionalSudoPrefix + 'apt-get install -y openssh-client xz-utils');
}

const tmateArch = TMATE_ARCH_MAP[external_os_default().arch()];
if (!tmateArch) {
throw new Error(`Unsupported architecture: ${external_os_default().arch()}`)
}
const tmateReleaseTar = await tool_cache.downloadTool(`https://github.com/tmate-io/tmate/releases/download/${TMATE_LINUX_VERSION}/tmate-${TMATE_LINUX_VERSION}-static-linux-${tmateArch}.tar.xz`);
const tmateDir = external_path_default().join(external_os_default().tmpdir(), "tmate")
tmateExecutable = external_path_default().join(tmateDir, "tmate")
const tmateArch = TMATE_ARCH_MAP[external_os_default().arch()];
if (!tmateArch) {
throw new Error(`Unsupported architecture: ${external_os_default().arch()}`)
}
const tmateReleaseTar = await tool_cache.downloadTool(`https://github.com/tmate-io/tmate/releases/download/${TMATE_LINUX_VERSION}/tmate-${TMATE_LINUX_VERSION}-static-linux-${tmateArch}.tar.xz`);
const tmateDir = external_path_default().join(external_os_default().tmpdir(), "tmate")
tmateExecutable = external_path_default().join(tmateDir, "tmate")

if (external_fs_default().existsSync(tmateExecutable))
external_fs_default().unlinkSync(tmateExecutable)
external_fs_default().mkdirSync(tmateDir, { recursive: true })
await execShellCommand(`tar x -C ${tmateDir} -f ${tmateReleaseTar} --strip-components=1`)
external_fs_default().unlinkSync(tmateReleaseTar)
if (external_fs_default().existsSync(tmateExecutable))
external_fs_default().unlinkSync(tmateExecutable)
external_fs_default().mkdirSync(tmateDir, { recursive: true })
await execShellCommand(`tar x -C ${tmateDir} -f ${tmateReleaseTar} --strip-components=1`)
external_fs_default().unlinkSync(tmateReleaseTar)
}
core.debug("Installed dependencies successfully");
}

core.debug("Installed dependencies successfully");

if (process.platform !== "win32") {
if (process.platform === "win32") {
tmateExecutable = 'CHERE_INVOKING=1 tmate'
} else {
core.debug("Generating SSH keys")
external_fs_default().mkdirSync(external_path_default().join(external_os_default().homedir(), ".ssh"), { recursive: true })
try {
Expand Down
66 changes: 34 additions & 32 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,44 +25,46 @@ const TMATE_ARCH_MAP = {
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

export async function run() {
const optionalSudoPrefix = core.getInput('sudo') === "true" ? "sudo " : "";
try {
core.debug("Installing dependencies")
let tmateExecutable = "tmate"
if (process.platform === "darwin") {
await execShellCommand('brew install tmate');
} else if (process.platform === "win32") {
await execShellCommand('pacman -Sy --noconfirm tmate');
tmateExecutable = 'CHERE_INVOKING=1 tmate'
} else {
const distro = await getLinuxDistro();
core.debug("linux distro: [" + distro + "]");
if (distro === "alpine") {
// for set -e workaround, we need to install bash because alpine doesn't have it
await execShellCommand(optionalSudoPrefix + 'apk add openssh-client xz bash');
if (core.getInput("install-dependencies") !== "false") {
core.debug("Installing dependencies")
if (process.platform === "darwin") {
await execShellCommand('brew install tmate');
} else if (process.platform === "win32") {
await execShellCommand('pacman -Sy --noconfirm tmate');
} else {
await execShellCommand(optionalSudoPrefix + 'apt-get update');
await execShellCommand(optionalSudoPrefix + 'apt-get install -y openssh-client xz-utils');
}

const tmateArch = TMATE_ARCH_MAP[os.arch()];
if (!tmateArch) {
throw new Error(`Unsupported architecture: ${os.arch()}`)
const optionalSudoPrefix = core.getInput("sudo") === "true" ? "sudo " : "";
const distro = await getLinuxDistro();
core.debug("linux distro: [" + distro + "]");
if (distro === "alpine") {
// for set -e workaround, we need to install bash because alpine doesn't have it
await execShellCommand(optionalSudoPrefix + 'apk add openssh-client xz bash');
} else {
await execShellCommand(optionalSudoPrefix + 'apt-get update');
await execShellCommand(optionalSudoPrefix + 'apt-get install -y openssh-client xz-utils');
}

const tmateArch = TMATE_ARCH_MAP[os.arch()];
if (!tmateArch) {
throw new Error(`Unsupported architecture: ${os.arch()}`)
}
const tmateReleaseTar = await tc.downloadTool(`https://github.com/tmate-io/tmate/releases/download/${TMATE_LINUX_VERSION}/tmate-${TMATE_LINUX_VERSION}-static-linux-${tmateArch}.tar.xz`);
const tmateDir = path.join(os.tmpdir(), "tmate")
tmateExecutable = path.join(tmateDir, "tmate")

if (fs.existsSync(tmateExecutable))
fs.unlinkSync(tmateExecutable)
fs.mkdirSync(tmateDir, { recursive: true })
await execShellCommand(`tar x -C ${tmateDir} -f ${tmateReleaseTar} --strip-components=1`)
fs.unlinkSync(tmateReleaseTar)
}
const tmateReleaseTar = await tc.downloadTool(`https://github.com/tmate-io/tmate/releases/download/${TMATE_LINUX_VERSION}/tmate-${TMATE_LINUX_VERSION}-static-linux-${tmateArch}.tar.xz`);
const tmateDir = path.join(os.tmpdir(), "tmate")
tmateExecutable = path.join(tmateDir, "tmate")

if (fs.existsSync(tmateExecutable))
fs.unlinkSync(tmateExecutable)
fs.mkdirSync(tmateDir, { recursive: true })
await execShellCommand(`tar x -C ${tmateDir} -f ${tmateReleaseTar} --strip-components=1`)
fs.unlinkSync(tmateReleaseTar)
core.debug("Installed dependencies successfully");
}

core.debug("Installed dependencies successfully");

if (process.platform !== "win32") {
if (process.platform === "win32") {
tmateExecutable = 'CHERE_INVOKING=1 tmate'
} else {
core.debug("Generating SSH keys")
fs.mkdirSync(path.join(os.homedir(), ".ssh"), { recursive: true })
try {
Expand Down
44 changes: 40 additions & 4 deletions src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,24 @@ describe('Tmate GitHub integration', () => {
Object.defineProperty(process, "platform", {
value: "win32"
})
core.getInput.mockReturnValueOnce("true").mockReturnValue("false")
core.getInput.mockReturnValueOnce("true").mockReturnValueOnce("false")
const customConnectionString = "foobar"
execShellCommand.mockReturnValue(Promise.resolve(customConnectionString))
await run()
expect(execShellCommand).toHaveBeenNthCalledWith(1, "pacman -Sy --noconfirm tmate")
expect(execShellCommand).toHaveBeenNthCalledWith(1, "pacman -Sy --noconfirm tmate");
expect(core.info).toHaveBeenNthCalledWith(1, `Web shell: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(2, `SSH: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(3, "Exiting debugging session because the continue file was created");
});
it('should handle the main loop for Windows without dependency installation', async () => {
Object.defineProperty(process, "platform", {
value: "win32"
})
core.getInput.mockReturnValueOnce("false")
const customConnectionString = "foobar"
execShellCommand.mockReturnValue(Promise.resolve(customConnectionString))
await run()
expect(execShellCommand).not.toHaveBeenNthCalledWith(1, "pacman -Sy --noconfirm tmate");
expect(core.info).toHaveBeenNthCalledWith(1, `Web shell: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(2, `SSH: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(3, "Exiting debugging session because the continue file was created");
Expand All @@ -41,7 +54,7 @@ describe('Tmate GitHub integration', () => {
Object.defineProperty(process, "platform", {
value: "linux"
})
core.getInput.mockReturnValueOnce("true").mockReturnValue("false")
core.getInput.mockReturnValueOnce("true").mockReturnValueOnce("true").mockReturnValueOnce("false")
const customConnectionString = "foobar"
execShellCommand.mockReturnValue(Promise.resolve(customConnectionString))
await run()
Expand All @@ -54,7 +67,7 @@ describe('Tmate GitHub integration', () => {
Object.defineProperty(process, "platform", {
value: "linux"
})
core.getInput.mockReturnValue("false")
core.getInput.mockReturnValueOnce("true").mockReturnValueOnce("false").mockReturnValueOnce("false")
const customConnectionString = "foobar"
execShellCommand.mockReturnValue(Promise.resolve(customConnectionString))
await run()
Expand All @@ -63,11 +76,34 @@ describe('Tmate GitHub integration', () => {
expect(core.info).toHaveBeenNthCalledWith(2, `SSH: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(3, "Exiting debugging session because the continue file was created");
});
it('should be handle the main loop for linux without installing dependencies', async () => {
Object.defineProperty(process, "platform", {
value: "linux"
})
core.getInput.mockReturnValueOnce("false").mockReturnValueOnce("false")
const customConnectionString = "foobar"
execShellCommand.mockReturnValue(Promise.resolve(customConnectionString))
await run()
expect(execShellCommand).not.toHaveBeenNthCalledWith(1, "apt-get update")
expect(core.info).toHaveBeenNthCalledWith(1, `Web shell: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(2, `SSH: ${customConnectionString}`);
expect(core.info).toHaveBeenNthCalledWith(3, "Exiting debugging session because the continue file was created");
});
it('should install tmate via brew for darwin', async () => {
Object.defineProperty(process, "platform", {
value: "darwin"
})
core.getInput.mockReturnValueOnce("true")
await run()
expect(core.getInput).toHaveBeenNthCalledWith(1, "install-dependencies")
expect(execShellCommand).toHaveBeenNthCalledWith(1, "brew install tmate")
});
it('should not install dependencies for darwin', async () => {
Object.defineProperty(process, "platform", {
value: "darwin"
})
core.getInput.mockReturnValueOnce("false")
await run()
expect(execShellCommand).not.toHaveBeenNthCalledWith(1, "brew install tmate")
});
});

0 comments on commit f309efd

Please sign in to comment.