5 Commits

Author SHA1 Message Date
octoturge 9482a0a2a7 ci: build every template's image independently, skip only failed ones
Provision Coder Templates / provision (push) Successful in 2m5s
Provision Coder Templates / build-images (push) Failing after 16s
Fixes a regression where the whole provision job (all 6 templates) was
skipped whenever build-web-image failed, since Actions skips a job whose
needs: dependency failed by default. Generalizes the single web-image
build step into a loop over every templates/*/Dockerfile, building and
pushing each independently so one failure doesn't block the rest, and
reports failures via a job output. provision now runs unconditionally
(if: always()) and skips pushing only the specific template(s) whose
image build failed this run, leaving their previous working version in
place instead of pushing one with no matching registry tag.
2026-08-27 01:18:25 +02:00
octoturge 278023e4c2 ci: drop redundant docker.sock mount in build-web-image
First real run of the new job failed at container creation:
"Error response from daemon: Duplicate mount point: /var/run/docker.sock".
The docker-build runner's config.yaml has docker_host: "" (not "-"),
which means act_runner already auto-injects the host socket into job
containers on its own - the workflow's explicit
container.volumes mount for the same path was a second, conflicting
request for it. Just dropping the explicit mount; the runner already
provides it.
2026-08-27 01:12:35 +02:00
octoturge 6de3196faa web: build image in CI, pull it in Terraform instead of building locally
Provision Coder Templates / build-web-image (push) Failing after 17s
Provision Coder Templates / provision (push) Has been skipped
templates/web's docker_image resource used a `build` block, so every
first-use of a new Dockerfile hash triggered a from-scratch build
(including the ~15-20min Rust toolchain compile) right at `terraform
apply` time - i.e. while someone was waiting to create a workspace.

Adds a build-web-image job to coder-templates.yml that builds and pushes
git.octoturge.com/octo-tech/profiles-web:<dockerfile-sha1> to this
instance's container registry, tagged identically to what
docker_image.web now computes and pulls (no build block). provision now
depends on build-web-image so a template never gets pushed pointing at
an image that isn't there yet. Skips the build entirely if that tag's
already in the registry, so an unrelated templates/* change doesn't
pay any cost.

Runs on a new dedicated "docker-build" runner (profiles-web-build),
scoped to just this repo via a repo-level registration token, with
host Docker socket access - deliberately not added to the existing
shared runner-1, which has no such access and stays untouched. Repo is
public, so the pulled image needs no registry auth; the push does, via
a new GITEA_PACKAGE_TOKEN repo secret (write:package scope).

Since CI and this Coder deployment share the same Docker daemon, the
"pull" is normally a same-host cache hit, not a real network pull.

Verified: `terraform validate` passes against the updated
templates/web/main.tf (run directly inside the coder-server container,
which has terraform embedded).
2026-08-27 01:10:58 +02:00
octoturge 730af0a335 cli-setup-wizard: stop parsing tea's config.yml, use tea itself
Provision Coder Templates / provision (push) Successful in 2m4s
DID_GITEA detection and the SSH/GPG key uploads to Gitea were reading
tea's config.yml directly with awk, assuming 2-space indentation and a
plaintext `token:` field. Neither holds: the real format uses 6-space
indentation for fields under each login, and a login done via OAuth
(tea's default flow) has no token field in the file at all - it's held
elsewhere. Confirmed live: a workspace with a genuinely active `tea`
OAuth login was still reporting "not logged in" and skipping the whole
key-setup step because of this.

Replaced with tea's own subcommands, which handle auth internally
regardless of method:
  - detection: `tea whoami`
  - SSH key upload: `tea ssh-keys add`
  - GPG key upload: `tea api -X POST /user/gpg_keys -F armored_public_key=@-`

Verified all three directly against the live account (disposable test
SSH + GPG keys, added then removed) - SSH upload succeeded; the GPG
upload correctly failed for an unrelated, expected reason (Gitea
requires the key's email to match a verified account email, and the
test key used a throwaway address), confirming the request itself is
well-formed.
2026-08-27 00:49:20 +02:00
octoturge d60e44508a cli-setup-wizard: explain why SSH/GPG key setup got skipped
Provision Coder Templates / provision (push) Successful in 2m7s
The SSH/GPG key-generation question only fires when gh/tea are actually
logged in (DID_GITHUB/DID_GITEA), which is correct - but if login was
declined, failed, or never completed, the section was skipped with zero
explanation. From the user's side that looked like a missing feature
rather than an unfinished login.

Confirmed on a live workspace: gh was never installed, and tea was
installed but `tea login add` never actually completed (no
~/.config/tea/config.yml), so the gate correctly stayed closed - the
user just had no way to know why. Now prints a one-line hint (only when
gh or tea is installed at all) pointing at the login command and the
--force re-run.
2026-08-27 00:14:11 +02:00
8 changed files with 182 additions and 108 deletions
+81 -3
View File
@@ -13,6 +13,26 @@ name: Provision Coder Templates
# CODER_URL e.g. https://code.octoturge.com # CODER_URL e.g. https://code.octoturge.com
# CODER_SESSION_TOKEN a token from `coder tokens create`, ideally under a # CODER_SESSION_TOKEN a token from `coder tokens create`, ideally under a
# dedicated service account rather than a personal one # dedicated service account rather than a personal one
# GITEA_PACKAGE_TOKEN a Gitea access token (user Settings > Applications)
# with write:package scope, for pushing each
# Dockerfile-having template's image to this
# instance's container registry. Only the octoturge
# account's own token is used - docker login below
# hardcodes that username to match.
#
# Any templates/<env>/ that has its own Dockerfile gets its image built and
# pushed here (build-images, on the dedicated "docker-build" runner - see
# templates/web/main.tf for why: that runner is scoped to this repo only and
# has host Docker socket access that the shared runner-1 deliberately
# doesn't). provision then just pulls the tag build-images produced, instead
# of building it itself at `terraform apply` time - keeps a slow toolchain
# compile off of "someone is waiting to create a workspace".
#
# Each template's image is built independently - one Dockerfile failing to
# build doesn't stop the others from building, and provision skips pushing
# only the specific template(s) whose image build failed this run (leaving
# their previous, already-working Coder template version in place) rather
# than skipping every template or pushing one with no matching image.
on: on:
push: push:
@@ -23,11 +43,62 @@ on:
workflow_dispatch: {} workflow_dispatch: {}
jobs: jobs:
build-images:
# The docker-build runner's docker_host: "" setting already auto-injects
# /var/run/docker.sock into job containers - an explicit
# container.volumes mount for the same path here fails at container
# creation with "Duplicate mount point: /var/run/docker.sock".
runs-on: docker-build
outputs:
failed_templates: ${{ steps.build.outputs.failed_templates }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build and push every template's image (skips a tag that's already in the registry)
id: build
run: |
set -e
echo "${{ secrets.GITEA_PACKAGE_TOKEN }}" | docker login git.octoturge.com -u octoturge --password-stdin
FAILED=""
for dockerfile in templates/*/Dockerfile; do
[ -e "$dockerfile" ] || continue
dir="$(dirname "$dockerfile")"
name="$(basename "$dir")"
TAG="$(sha1sum "$dockerfile" | cut -d' ' -f1)"
IMAGE="git.octoturge.com/octo-tech/profiles-${name}:${TAG}"
echo "::group::${name}"
if docker manifest inspect "$IMAGE" >/dev/null 2>&1; then
echo "$IMAGE already in the registry (Dockerfile unchanged), skipping build."
elif docker build -t "$IMAGE" "$dir" && docker push "$IMAGE"; then
echo "Built and pushed $IMAGE"
else
echo "::warning::Failed to build/push $IMAGE - templates/$name will be skipped this run."
FAILED="$FAILED $name"
fi
echo "::endgroup::"
done
echo "failed_templates=${FAILED# }" >> "$GITHUB_OUTPUT"
provision: provision:
# needs: build-images orders this after the image builds (so a fresh
# template push never points at a tag that isn't in the registry yet)
# without making every template's reprovisioning depend on ALL builds
# succeeding - if:always() overrides the default "skip if a dependency
# failed" behavior, since build-images only fails outright on an
# infra-level problem (e.g. registry login); a single template's build
# failure is reported via failed_templates instead and only skips that
# one template below.
needs: build-images
if: always()
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
CODER_URL: ${{ secrets.CODER_URL }} CODER_URL: ${{ secrets.CODER_URL }}
CODER_SESSION_TOKEN: ${{ secrets.CODER_SESSION_TOKEN }} CODER_SESSION_TOKEN: ${{ secrets.CODER_SESSION_TOKEN }}
FAILED_TEMPLATES: ${{ needs.build-images.outputs.failed_templates }}
steps: steps:
- name: Checkout (full history, needed to detect removed templates) - name: Checkout (full history, needed to detect removed templates)
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -44,9 +115,16 @@ jobs:
run: | run: |
set -e set -e
for dir in templates/*/; do for dir in templates/*/; do
name="profiles-$(basename "$dir")" name="$(basename "$dir")"
echo "::group::Pushing $name from $dir" full="profiles-$name"
coder templates push "$name" -d "$dir" --yes \ case " $FAILED_TEMPLATES " in
*" $name "*)
echo "::warning::Skipping $full - its Docker image failed to build this run (see build-images), leaving the previous template version in place."
continue
;;
esac
echo "::group::Pushing $full from $dir"
coder templates push "$full" -d "$dir" --yes \
-m "auto-provisioned from ${GITHUB_SHA:0:12}" -m "auto-provisioned from ${GITHUB_SHA:0:12}"
echo "::endgroup::" echo "::endgroup::"
done done
+15 -16
View File
@@ -143,12 +143,11 @@ else
fi fi
fi fi
fi fi
TEA_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/tea/config.yml" # `tea whoami` succeeds regardless of how the login was done (personal
if command -v tea >/dev/null 2>&1 && [ -f "$TEA_CONFIG" ]; then # access token or OAuth) - more reliable than parsing tea's own
TEA_URL="$(awk '/^logins:/{f=1} f && /^ url:/{print $2; exit}' "$TEA_CONFIG")" # config.yml, whose indentation and fields (no plaintext `token:` at all
TEA_TOKEN="$(awk '/^logins:/{f=1} f && /^ token:/{print $2; exit}' "$TEA_CONFIG")" # for an OAuth login) vary by auth method.
[ -n "$TEA_URL" ] && [ -n "$TEA_TOKEN" ] && DID_GITEA=1 command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
fi
# --- SSH + GPG keys for the external git host(s) selected above --- # --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now - # Only asks if the user actually set up GitHub and/or Gitea just now -
@@ -186,13 +185,10 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
SSH_PUB_JSON="$(sed 's/\\/\\\\/g; s/"/\\"/g' "${SSH_KEY}.pub")" if tea ssh-keys add "${SSH_KEY}.pub" --title "coder-$(hostname)" >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"title\":\"coder-$(hostname)\",\"key\":\"${SSH_PUB_JSON}\"}" >/dev/null 2>&1; then
echo "SSH key added to Gitea." echo "SSH key added to Gitea."
else else
echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually with: tea ssh-keys add ${SSH_KEY}.pub"
fi fi
fi fi
@@ -226,17 +222,20 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
GPG_ARMORED_JSON="$(gpg --armor --export "$GPG_KEY_ID" | awk '{printf "%s\\n", $0}')" if gpg --armor --export "$GPG_KEY_ID" | tea api -X POST /user/gpg_keys -F armored_public_key=@- >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/gpg_keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"armored_public_key\":\"${GPG_ARMORED_JSON}\"}" >/dev/null 2>&1; then
echo "GPG key added to Gitea." echo "GPG key added to Gitea."
else else
echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually: gpg --armor --export $GPG_KEY_ID | tea api -X POST /user/gpg_keys -F armored_public_key=@-"
fi fi
fi fi
fi fi
fi fi
elif command -v gh >/dev/null 2>&1 || command -v tea >/dev/null 2>&1; then
# gh and/or tea are installed but neither is actually logged in yet (login
# was declined, failed, or never completed) - say why the key-generation
# question above got skipped instead of just silently not asking.
echo "Skipping SSH/GPG key setup: not logged in to GitHub or Gitea yet."
echo "Log in (gh auth login / tea login add) then re-run: bash /opt/coder/cli-setup-wizard.sh --force"
fi fi
echo "" echo ""
+15 -16
View File
@@ -143,12 +143,11 @@ else
fi fi
fi fi
fi fi
TEA_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/tea/config.yml" # `tea whoami` succeeds regardless of how the login was done (personal
if command -v tea >/dev/null 2>&1 && [ -f "$TEA_CONFIG" ]; then # access token or OAuth) - more reliable than parsing tea's own
TEA_URL="$(awk '/^logins:/{f=1} f && /^ url:/{print $2; exit}' "$TEA_CONFIG")" # config.yml, whose indentation and fields (no plaintext `token:` at all
TEA_TOKEN="$(awk '/^logins:/{f=1} f && /^ token:/{print $2; exit}' "$TEA_CONFIG")" # for an OAuth login) vary by auth method.
[ -n "$TEA_URL" ] && [ -n "$TEA_TOKEN" ] && DID_GITEA=1 command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
fi
# --- SSH + GPG keys for the external git host(s) selected above --- # --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now - # Only asks if the user actually set up GitHub and/or Gitea just now -
@@ -186,13 +185,10 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
SSH_PUB_JSON="$(sed 's/\\/\\\\/g; s/"/\\"/g' "${SSH_KEY}.pub")" if tea ssh-keys add "${SSH_KEY}.pub" --title "coder-$(hostname)" >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"title\":\"coder-$(hostname)\",\"key\":\"${SSH_PUB_JSON}\"}" >/dev/null 2>&1; then
echo "SSH key added to Gitea." echo "SSH key added to Gitea."
else else
echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually with: tea ssh-keys add ${SSH_KEY}.pub"
fi fi
fi fi
@@ -226,17 +222,20 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
GPG_ARMORED_JSON="$(gpg --armor --export "$GPG_KEY_ID" | awk '{printf "%s\\n", $0}')" if gpg --armor --export "$GPG_KEY_ID" | tea api -X POST /user/gpg_keys -F armored_public_key=@- >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/gpg_keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"armored_public_key\":\"${GPG_ARMORED_JSON}\"}" >/dev/null 2>&1; then
echo "GPG key added to Gitea." echo "GPG key added to Gitea."
else else
echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually: gpg --armor --export $GPG_KEY_ID | tea api -X POST /user/gpg_keys -F armored_public_key=@-"
fi fi
fi fi
fi fi
fi fi
elif command -v gh >/dev/null 2>&1 || command -v tea >/dev/null 2>&1; then
# gh and/or tea are installed but neither is actually logged in yet (login
# was declined, failed, or never completed) - say why the key-generation
# question above got skipped instead of just silently not asking.
echo "Skipping SSH/GPG key setup: not logged in to GitHub or Gitea yet."
echo "Log in (gh auth login / tea login add) then re-run: bash /opt/coder/cli-setup-wizard.sh --force"
fi fi
echo "" echo ""
+15 -16
View File
@@ -143,12 +143,11 @@ else
fi fi
fi fi
fi fi
TEA_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/tea/config.yml" # `tea whoami` succeeds regardless of how the login was done (personal
if command -v tea >/dev/null 2>&1 && [ -f "$TEA_CONFIG" ]; then # access token or OAuth) - more reliable than parsing tea's own
TEA_URL="$(awk '/^logins:/{f=1} f && /^ url:/{print $2; exit}' "$TEA_CONFIG")" # config.yml, whose indentation and fields (no plaintext `token:` at all
TEA_TOKEN="$(awk '/^logins:/{f=1} f && /^ token:/{print $2; exit}' "$TEA_CONFIG")" # for an OAuth login) vary by auth method.
[ -n "$TEA_URL" ] && [ -n "$TEA_TOKEN" ] && DID_GITEA=1 command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
fi
# --- SSH + GPG keys for the external git host(s) selected above --- # --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now - # Only asks if the user actually set up GitHub and/or Gitea just now -
@@ -186,13 +185,10 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
SSH_PUB_JSON="$(sed 's/\\/\\\\/g; s/"/\\"/g' "${SSH_KEY}.pub")" if tea ssh-keys add "${SSH_KEY}.pub" --title "coder-$(hostname)" >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"title\":\"coder-$(hostname)\",\"key\":\"${SSH_PUB_JSON}\"}" >/dev/null 2>&1; then
echo "SSH key added to Gitea." echo "SSH key added to Gitea."
else else
echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually with: tea ssh-keys add ${SSH_KEY}.pub"
fi fi
fi fi
@@ -226,17 +222,20 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
GPG_ARMORED_JSON="$(gpg --armor --export "$GPG_KEY_ID" | awk '{printf "%s\\n", $0}')" if gpg --armor --export "$GPG_KEY_ID" | tea api -X POST /user/gpg_keys -F armored_public_key=@- >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/gpg_keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"armored_public_key\":\"${GPG_ARMORED_JSON}\"}" >/dev/null 2>&1; then
echo "GPG key added to Gitea." echo "GPG key added to Gitea."
else else
echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually: gpg --armor --export $GPG_KEY_ID | tea api -X POST /user/gpg_keys -F armored_public_key=@-"
fi fi
fi fi
fi fi
fi fi
elif command -v gh >/dev/null 2>&1 || command -v tea >/dev/null 2>&1; then
# gh and/or tea are installed but neither is actually logged in yet (login
# was declined, failed, or never completed) - say why the key-generation
# question above got skipped instead of just silently not asking.
echo "Skipping SSH/GPG key setup: not logged in to GitHub or Gitea yet."
echo "Log in (gh auth login / tea login add) then re-run: bash /opt/coder/cli-setup-wizard.sh --force"
fi fi
echo "" echo ""
+15 -16
View File
@@ -143,12 +143,11 @@ else
fi fi
fi fi
fi fi
TEA_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/tea/config.yml" # `tea whoami` succeeds regardless of how the login was done (personal
if command -v tea >/dev/null 2>&1 && [ -f "$TEA_CONFIG" ]; then # access token or OAuth) - more reliable than parsing tea's own
TEA_URL="$(awk '/^logins:/{f=1} f && /^ url:/{print $2; exit}' "$TEA_CONFIG")" # config.yml, whose indentation and fields (no plaintext `token:` at all
TEA_TOKEN="$(awk '/^logins:/{f=1} f && /^ token:/{print $2; exit}' "$TEA_CONFIG")" # for an OAuth login) vary by auth method.
[ -n "$TEA_URL" ] && [ -n "$TEA_TOKEN" ] && DID_GITEA=1 command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
fi
# --- SSH + GPG keys for the external git host(s) selected above --- # --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now - # Only asks if the user actually set up GitHub and/or Gitea just now -
@@ -186,13 +185,10 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
SSH_PUB_JSON="$(sed 's/\\/\\\\/g; s/"/\\"/g' "${SSH_KEY}.pub")" if tea ssh-keys add "${SSH_KEY}.pub" --title "coder-$(hostname)" >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"title\":\"coder-$(hostname)\",\"key\":\"${SSH_PUB_JSON}\"}" >/dev/null 2>&1; then
echo "SSH key added to Gitea." echo "SSH key added to Gitea."
else else
echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually with: tea ssh-keys add ${SSH_KEY}.pub"
fi fi
fi fi
@@ -226,17 +222,20 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
GPG_ARMORED_JSON="$(gpg --armor --export "$GPG_KEY_ID" | awk '{printf "%s\\n", $0}')" if gpg --armor --export "$GPG_KEY_ID" | tea api -X POST /user/gpg_keys -F armored_public_key=@- >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/gpg_keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"armored_public_key\":\"${GPG_ARMORED_JSON}\"}" >/dev/null 2>&1; then
echo "GPG key added to Gitea." echo "GPG key added to Gitea."
else else
echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually: gpg --armor --export $GPG_KEY_ID | tea api -X POST /user/gpg_keys -F armored_public_key=@-"
fi fi
fi fi
fi fi
fi fi
elif command -v gh >/dev/null 2>&1 || command -v tea >/dev/null 2>&1; then
# gh and/or tea are installed but neither is actually logged in yet (login
# was declined, failed, or never completed) - say why the key-generation
# question above got skipped instead of just silently not asking.
echo "Skipping SSH/GPG key setup: not logged in to GitHub or Gitea yet."
echo "Log in (gh auth login / tea login add) then re-run: bash /opt/coder/cli-setup-wizard.sh --force"
fi fi
echo "" echo ""
+15 -16
View File
@@ -143,12 +143,11 @@ else
fi fi
fi fi
fi fi
TEA_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/tea/config.yml" # `tea whoami` succeeds regardless of how the login was done (personal
if command -v tea >/dev/null 2>&1 && [ -f "$TEA_CONFIG" ]; then # access token or OAuth) - more reliable than parsing tea's own
TEA_URL="$(awk '/^logins:/{f=1} f && /^ url:/{print $2; exit}' "$TEA_CONFIG")" # config.yml, whose indentation and fields (no plaintext `token:` at all
TEA_TOKEN="$(awk '/^logins:/{f=1} f && /^ token:/{print $2; exit}' "$TEA_CONFIG")" # for an OAuth login) vary by auth method.
[ -n "$TEA_URL" ] && [ -n "$TEA_TOKEN" ] && DID_GITEA=1 command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
fi
# --- SSH + GPG keys for the external git host(s) selected above --- # --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now - # Only asks if the user actually set up GitHub and/or Gitea just now -
@@ -186,13 +185,10 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
SSH_PUB_JSON="$(sed 's/\\/\\\\/g; s/"/\\"/g' "${SSH_KEY}.pub")" if tea ssh-keys add "${SSH_KEY}.pub" --title "coder-$(hostname)" >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"title\":\"coder-$(hostname)\",\"key\":\"${SSH_PUB_JSON}\"}" >/dev/null 2>&1; then
echo "SSH key added to Gitea." echo "SSH key added to Gitea."
else else
echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually with: tea ssh-keys add ${SSH_KEY}.pub"
fi fi
fi fi
@@ -226,17 +222,20 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
GPG_ARMORED_JSON="$(gpg --armor --export "$GPG_KEY_ID" | awk '{printf "%s\\n", $0}')" if gpg --armor --export "$GPG_KEY_ID" | tea api -X POST /user/gpg_keys -F armored_public_key=@- >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/gpg_keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"armored_public_key\":\"${GPG_ARMORED_JSON}\"}" >/dev/null 2>&1; then
echo "GPG key added to Gitea." echo "GPG key added to Gitea."
else else
echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually: gpg --armor --export $GPG_KEY_ID | tea api -X POST /user/gpg_keys -F armored_public_key=@-"
fi fi
fi fi
fi fi
fi fi
elif command -v gh >/dev/null 2>&1 || command -v tea >/dev/null 2>&1; then
# gh and/or tea are installed but neither is actually logged in yet (login
# was declined, failed, or never completed) - say why the key-generation
# question above got skipped instead of just silently not asking.
echo "Skipping SSH/GPG key setup: not logged in to GitHub or Gitea yet."
echo "Log in (gh auth login / tea login add) then re-run: bash /opt/coder/cli-setup-wizard.sh --force"
fi fi
echo "" echo ""
+15 -16
View File
@@ -143,12 +143,11 @@ else
fi fi
fi fi
fi fi
TEA_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/tea/config.yml" # `tea whoami` succeeds regardless of how the login was done (personal
if command -v tea >/dev/null 2>&1 && [ -f "$TEA_CONFIG" ]; then # access token or OAuth) - more reliable than parsing tea's own
TEA_URL="$(awk '/^logins:/{f=1} f && /^ url:/{print $2; exit}' "$TEA_CONFIG")" # config.yml, whose indentation and fields (no plaintext `token:` at all
TEA_TOKEN="$(awk '/^logins:/{f=1} f && /^ token:/{print $2; exit}' "$TEA_CONFIG")" # for an OAuth login) vary by auth method.
[ -n "$TEA_URL" ] && [ -n "$TEA_TOKEN" ] && DID_GITEA=1 command -v tea >/dev/null 2>&1 && tea whoami >/dev/null 2>&1 && DID_GITEA=1
fi
# --- SSH + GPG keys for the external git host(s) selected above --- # --- SSH + GPG keys for the external git host(s) selected above ---
# Only asks if the user actually set up GitHub and/or Gitea just now - # Only asks if the user actually set up GitHub and/or Gitea just now -
@@ -186,13 +185,10 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
SSH_PUB_JSON="$(sed 's/\\/\\\\/g; s/"/\\"/g' "${SSH_KEY}.pub")" if tea ssh-keys add "${SSH_KEY}.pub" --title "coder-$(hostname)" >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"title\":\"coder-$(hostname)\",\"key\":\"${SSH_PUB_JSON}\"}" >/dev/null 2>&1; then
echo "SSH key added to Gitea." echo "SSH key added to Gitea."
else else
echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the SSH key to Gitea automatically (may already be added). Add manually with: tea ssh-keys add ${SSH_KEY}.pub"
fi fi
fi fi
@@ -226,17 +222,20 @@ if [ "$DID_GITHUB" -eq 1 ] || [ "$DID_GITEA" -eq 1 ]; then
fi fi
if [ "$DID_GITEA" -eq 1 ]; then if [ "$DID_GITEA" -eq 1 ]; then
GPG_ARMORED_JSON="$(gpg --armor --export "$GPG_KEY_ID" | awk '{printf "%s\\n", $0}')" if gpg --armor --export "$GPG_KEY_ID" | tea api -X POST /user/gpg_keys -F armored_public_key=@- >/dev/null 2>&1; then
if curl -fsS -X POST "${TEA_URL%/}/api/v1/user/gpg_keys" \
-H "Authorization: token ${TEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"armored_public_key\":\"${GPG_ARMORED_JSON}\"}" >/dev/null 2>&1; then
echo "GPG key added to Gitea." echo "GPG key added to Gitea."
else else
echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually at: ${TEA_URL%/}/user/settings/keys" echo "Couldn't add the GPG key to Gitea automatically (may already be added). Add manually: gpg --armor --export $GPG_KEY_ID | tea api -X POST /user/gpg_keys -F armored_public_key=@-"
fi fi
fi fi
fi fi
fi fi
elif command -v gh >/dev/null 2>&1 || command -v tea >/dev/null 2>&1; then
# gh and/or tea are installed but neither is actually logged in yet (login
# was declined, failed, or never completed) - say why the key-generation
# question above got skipped instead of just silently not asking.
echo "Skipping SSH/GPG key setup: not logged in to GitHub or Gitea yet."
echo "Log in (gh auth login / tea login add) then re-run: bash /opt/coder/cli-setup-wizard.sh --force"
fi fi
echo "" echo ""
+11 -9
View File
@@ -193,16 +193,18 @@ resource "docker_volume" "home_volume" {
} }
} }
# Builds the full Web Applications toolchain (Rust/Tauri 2, Bun/Node/pnpm, # Pulls the full Web Applications toolchain (Rust/Tauri 2, Bun/Node/pnpm,
# Python CV/ONNX, DB clients - see ./Dockerfile) from this template's own # Python CV/ONNX, DB clients - see ./Dockerfile) instead of building it here.
# directory, so no external registry push is required. The tag embeds the # The image is built and pushed by .gitea/workflows/coder-templates.yml's
# Dockerfile's hash so a Dockerfile edit forces a rebuild on next apply/push, # build-web-image job, tagged with the same Dockerfile hash this resource
# while an unchanged Dockerfile reuses the cached image. # computes - so a Dockerfile edit always resolves to the matching image, and
# an unchanged Dockerfile resolves to one already built (CI skips rebuilding
# it, and this pull is normally a same-host cache hit rather than a real
# network pull, since CI and this Coder deployment share one Docker daemon).
# Moves the ~15-20min Rust toolchain compile off of "someone is waiting to
# create a workspace" and onto CI, where it runs once per Dockerfile change.
resource "docker_image" "web" { resource "docker_image" "web" {
name = "coder-profiles-web:${filesha1("${path.module}/Dockerfile")}" name = "git.octoturge.com/octo-tech/profiles-web:${filesha1("${path.module}/Dockerfile")}"
build {
context = path.module
}
keep_locally = true keep_locally = true
} }