Improve portability
parent
751f431767
commit
610947eefb
@ -0,0 +1,94 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import {
|
||||
createJSONResponse,
|
||||
execContainer,
|
||||
executeScriptInContainer,
|
||||
findResourceInstance,
|
||||
runContainer,
|
||||
runTerraformApply,
|
||||
runTerraformInit,
|
||||
testRequiredVariables,
|
||||
} from "../test";
|
||||
import { serve } from "bun";
|
||||
|
||||
describe("slackme", async () => {
|
||||
await runTerraformInit(import.meta.dir);
|
||||
|
||||
testRequiredVariables(import.meta.dir, {
|
||||
agent_id: "foo",
|
||||
auth_provider_id: "foo",
|
||||
});
|
||||
|
||||
const setupContainer = async (image = "alpine") => {
|
||||
const state = await runTerraformApply(import.meta.dir, {
|
||||
agent_id: "foo",
|
||||
auth_provider_id: "foo",
|
||||
});
|
||||
const instance = findResourceInstance(state, "coder_script");
|
||||
const id = await runContainer(image);
|
||||
return { id, instance };
|
||||
};
|
||||
|
||||
const writeCoder = async (id: string, script: string) => {
|
||||
const exec = await execContainer(id, [
|
||||
"sh",
|
||||
"-c",
|
||||
`echo '${script}' > /usr/bin/coder && chmod +x /usr/bin/coder`,
|
||||
]);
|
||||
expect(exec.exitCode).toBe(0);
|
||||
};
|
||||
|
||||
it("writes to path as executable", async () => {
|
||||
const { instance, id } = await setupContainer();
|
||||
await writeCoder(id, "exit 0");
|
||||
let exec = await execContainer(id, ["sh", "-c", instance.script]);
|
||||
expect(exec.exitCode).toBe(0);
|
||||
exec = await execContainer(id, ["sh", "-c", "which slackme"]);
|
||||
expect(exec.exitCode).toBe(0);
|
||||
expect(exec.stdout.trim()).toEqual("/usr/bin/slackme");
|
||||
});
|
||||
|
||||
it("prints usage with no command", async () => {
|
||||
const { instance, id } = await setupContainer();
|
||||
await writeCoder(id, "echo 👋");
|
||||
let exec = await execContainer(id, ["sh", "-c", instance.script]);
|
||||
expect(exec.exitCode).toBe(0);
|
||||
exec = await execContainer(id, ["sh", "-c", "slackme"]);
|
||||
expect(exec.stdout.trim()).toStartWith(
|
||||
"slackme — Send a Slack notification when a command finishes"
|
||||
);
|
||||
});
|
||||
|
||||
it("displays url when not authenticated", async () => {
|
||||
const { instance, id } = await setupContainer();
|
||||
await writeCoder(id, "echo 'some-url' && exit 1");
|
||||
let exec = await execContainer(id, ["sh", "-c", instance.script]);
|
||||
expect(exec.exitCode).toBe(0);
|
||||
exec = await execContainer(id, ["sh", "-c", "slackme echo test"]);
|
||||
expect(exec.stdout.trim()).toEndWith("some-url");
|
||||
});
|
||||
|
||||
it("curls url when authenticated", async () => {
|
||||
let url: URL
|
||||
const fakeSlackHost = serve({
|
||||
fetch: (req) => {
|
||||
url = new URL(req.url);
|
||||
if (url.pathname === "/api/chat.postMessage")
|
||||
return createJSONResponse({
|
||||
ok: true,
|
||||
});
|
||||
return createJSONResponse({}, 404);
|
||||
},
|
||||
port: 0,
|
||||
});
|
||||
|
||||
const { instance, id } = await setupContainer("alpine/curl");
|
||||
await writeCoder(id, "echo 'token'");
|
||||
let exec = await execContainer(id, ["sh", "-c", instance.script]);
|
||||
expect(exec.exitCode).toBe(0);
|
||||
exec = await execContainer(id, ["sh", "-c", `SLACK_URL="http://${fakeSlackHost.hostname}:${fakeSlackHost.port}" slackme echo test`]);
|
||||
expect(exec.stdout.trim()).toEndWith("test");
|
||||
expect(url.pathname).toEqual("/api/chat.postMessage");
|
||||
expect(url.searchParams.get("channel")).toEqual("token");
|
||||
});
|
||||
});
|
@ -1,28 +1,38 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env sh
|
||||
|
||||
PROVIDER_ID=${PROVIDER_ID}
|
||||
SLACK_MESSAGE="${SLACK_MESSAGE}"
|
||||
SLACK_URL=$${SLACK_URL:-https://slack.com}
|
||||
|
||||
BOT_TOKEN=\$(coder external-auth access-token $PROVIDER_ID)
|
||||
usage() {
|
||||
cat <<EOF
|
||||
slackme — Send a Slack notification when a command finishes
|
||||
Usage: slackme <command>
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Authenticate to run commands in the background:"
|
||||
# The output contains the URL if failed.
|
||||
echo $BOT_TOKEN
|
||||
Example: slackme npm run long-build
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
USER_ID=\$(coder external-auth access-token $PROVIDER_ID --extra "authed_user.id")
|
||||
|
||||
BOT_TOKEN=$(coder external-auth access-token $PROVIDER_ID)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to get authenticated user ID:"
|
||||
echo $USER_ID
|
||||
printf "Authenticate with Slack to be notified when a command finishes:\n$BOT_TOKEN\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "We'll notify you when done!"
|
||||
USER_ID=$(coder external-auth access-token $PROVIDER_ID --extra "authed_user.id")
|
||||
if [ $? -ne 0 ]; then
|
||||
printf "Failed to get authenticated user ID:\n$USER_ID\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run all arguments as a command
|
||||
$@
|
||||
|
||||
set -e
|
||||
curl --silent -o /dev/null --header "Authorization: Bearer $BOT_TOKEN" \
|
||||
"https://slack.com/api/chat.postMessage?channel=$USER_ID&text=Your%20command%20finished!&pretty=1"
|
||||
"$SLACK_URL/api/chat.postMessage?channel=$USER_ID&text=$SLACK_MESSAGE&pretty=1"
|
||||
|
Loading…
Reference in New Issue