Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions registry/coder/modules/github-upload-public-key/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ const setupServer = () => {
]);
}

// case: key exists on the second page
if (req.headers.get("Authorization") === "Bearer paginated") {
const perPage = Number(url.searchParams.get("per_page") ?? 30);
const page = Number(url.searchParams.get("page") ?? 1);
const keys = [
...Array.from({ length: perPage }, (_, i) => ({ key: `foo-${i}` })),
{ key: "exists" },
];
return createJSONResponse(
keys.slice((page - 1) * perPage, page * perPage),
);
}

// case: key does not exist
return createJSONResponse([
{
Expand Down Expand Up @@ -238,6 +251,23 @@ describe("github-upload-public-key", () => {
]);
});

it("finds an existing key on a later page", async () => {
const { id, run, uploads } = await setupContainer(undefined, {
key_type: "both",
});
await writeCoder(id, "echo paginated");

const exec = await run();
expect(exec.stdout).toContain(
"Your Coder public key is already a GitHub authentication key!",
);
expect(exec.stdout).toContain(
"Your Coder public key is already a GitHub signing key!",
);
expect(exec.exitCode).toBe(0);
expect(uploads).toEqual([]);
});

it("skips existing keys when key_type is both", async () => {
const { id, run, uploads } = await setupContainer(undefined, {
key_type: "both",
Expand Down
57 changes: 32 additions & 25 deletions registry/coder/modules/github-upload-public-key/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,38 @@ upload_key() {
local label="$2"

echo "Fetching $label keys from GitHub..."
local keys_response
keys_response=$(
curl -L -s \
-w "\n%%{http_code}" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"$GITHUB_API_URL/user/$endpoint"
)
local keys_status keys_body
keys_status=$(tail -n1 <<< "$keys_response")
keys_body=$(sed \$d <<< "$keys_response")

if [ "$keys_status" -ne 200 ]; then
echo "Failed to fetch GitHub $label keys with status code $keys_status!"
echo "$keys_body"
return 1
fi

local match
match=$(jq -r --arg PUBLIC_KEY "$PUBLIC_KEY" '.[] | select(.key == $PUBLIC_KEY) | .key' <<< "$keys_body")
if [ "$PUBLIC_KEY" = "$match" ]; then
echo "Your Coder public key is already a GitHub $label key!"
return 0
fi
local per_page=100 page=1
local keys_response keys_status keys_body match count
while true; do
keys_response=$(
curl -L -s \
-w "\n%%{http_code}" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"$GITHUB_API_URL/user/$endpoint?per_page=$per_page&page=$page"
)
keys_status=$(tail -n1 <<< "$keys_response")
keys_body=$(sed \$d <<< "$keys_response")

if [ "$keys_status" -ne 200 ]; then
echo "Failed to fetch GitHub $label keys with status code $keys_status!"
echo "$keys_body"
return 1
fi

match=$(jq -r --arg PUBLIC_KEY "$PUBLIC_KEY" '.[] | select(.key == $PUBLIC_KEY) | .key' <<< "$keys_body")
if [ "$PUBLIC_KEY" = "$match" ]; then
echo "Your Coder public key is already a GitHub $label key!"
return 0
fi

count=$(jq 'length' <<< "$keys_body")
if [ "$count" -lt "$per_page" ]; then
break
fi
page=$((page + 1))
done

echo "Your Coder public key is not a GitHub $label key yet. Adding it now..."
local upload_response
Expand Down
Loading