140 lines
5.1 KiB
YAML
140 lines
5.1 KiB
YAML
name: CI TEST (Vault secrets)
|
||
|
||
on:
|
||
push:
|
||
branches: [ main, master ]
|
||
|
||
jobs:
|
||
build:
|
||
runs-on: [self-hosted, linux, docker]
|
||
container:
|
||
image: node:24.13-alpine3.22
|
||
options: --network host
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: https://gitea.nikitapozd.dev/actions/checkout@v6
|
||
|
||
- name: Bootstrap network tools
|
||
run: |
|
||
set -eux
|
||
# wget/curl/ca-certificates + dns tools
|
||
apk add --no-cache ca-certificates wget curl jq bind-tools busybox-extras
|
||
update-ca-certificates || true
|
||
|
||
- name: Network smoke test (verbose)
|
||
run: |
|
||
set -eux
|
||
echo "=== IP / route ==="
|
||
ip addr
|
||
ip route
|
||
echo "=== resolv.conf ==="
|
||
cat /etc/resolv.conf || true
|
||
|
||
echo "=== DNS (A/AAAA) ==="
|
||
nslookup -type=A dl-cdn.alpinelinux.org || true
|
||
nslookup -type=AAAA dl-cdn.alpinelinux.org || true
|
||
|
||
echo "=== TCP 443 check ==="
|
||
# busybox-extras дает nc
|
||
nc -vz dl-cdn.alpinelinux.org 443 || true
|
||
|
||
echo "=== HTTPS HEAD via curl (IPv4 forced) ==="
|
||
curl -4 -vI --max-time 10 https://dl-cdn.alpinelinux.org/ || true
|
||
|
||
echo "=== APKINDEX download via wget (IPv4 forced, debug) ==="
|
||
# важное: именно APKINDEX, как в apk
|
||
wget -4 --debug -S -O /dev/null --timeout=10 --tries=1 \
|
||
https://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz
|
||
|
||
- name: APK update/add (verbose)
|
||
run: |
|
||
set -eux
|
||
export APK_PROGRESS=plain
|
||
# если тут зависнет — значит проблема точно на fetch layer
|
||
apk update -v --no-progress
|
||
apk add -v --no-cache curl jq
|
||
|
||
- name: Get Keycloak access token from Gitea secrets
|
||
env:
|
||
KEYCLOAK_TOKEN_URL: ${{ secrets.KEYCLOAK_TOKEN_URL }}
|
||
KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }}
|
||
KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }}
|
||
run: |
|
||
TOKEN_RESPONSE=$(curl -sS -X POST "$KEYCLOAK_TOKEN_URL" \
|
||
-d "grant_type=client_credentials" \
|
||
-d "client_id=$KEYCLOAK_CLIENT_ID" \
|
||
-d "client_secret=$KEYCLOAK_CLIENT_SECRET")
|
||
|
||
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')
|
||
|
||
if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" = "null" ]; then
|
||
echo "ERROR: Failed to obtain access_token from Keycloak"
|
||
echo "$TOKEN_RESPONSE" | jq .
|
||
exit 1
|
||
fi
|
||
|
||
# Не печатай токен в лог
|
||
echo "ACCESS_TOKEN=$ACCESS_TOKEN" >> "$GITHUB_ENV"
|
||
|
||
- name: Exchange Keycloak token for Vault token (auth/jwt/login)
|
||
env:
|
||
VAULT_ADDRESS: ${{ secrets.VAULT_ADDRESS }}
|
||
VAULT_JWT_ROLE: ${{ secrets.VAULT_ROLE }}
|
||
run: |
|
||
LOGIN_RESPONSE=$(curl -sS -X POST "$VAULT_ADDRESS/v1/auth/jwt/login" \
|
||
-H "Content-Type: application/json" \
|
||
-d "{\"role\":\"$VAULT_JWT_ROLE\",\"jwt\":\"$ACCESS_TOKEN\"}")
|
||
|
||
VAULT_TOKEN=$(echo "$LOGIN_RESPONSE" | jq -r '.auth.client_token')
|
||
|
||
if [ -z "$VAULT_TOKEN" ] || [ "$VAULT_TOKEN" = "null" ]; then
|
||
echo "ERROR: Failed to login to Vault via JWT"
|
||
echo "$LOGIN_RESPONSE" | jq .
|
||
exit 1
|
||
fi
|
||
|
||
echo "VAULT_TOKEN=$VAULT_TOKEN" >> "$GITHUB_ENV"
|
||
|
||
- name: Read secrets from Vault KV and export to env
|
||
env:
|
||
VAULT_ADDRESS: ${{ secrets.VAULT_ADDRESS }}
|
||
VAULT_KV_PATH: ${{ secrets.VAULT_KV_PATH }}
|
||
run: |
|
||
# KV v2 API endpoint: /v1/<mount>/data/<path>
|
||
# Если VAULT_KV_PATH="blog/frontend", то mount=blog, path=frontend
|
||
|
||
MOUNT="${VAULT_KV_PATH%%/*}"
|
||
SUBPATH="${VAULT_KV_PATH#*/}"
|
||
|
||
JSON=$(curl -sS \
|
||
-H "X-Vault-Token: $VAULT_TOKEN" \
|
||
"$VAULT_ADDRESS/v1/$MOUNT/data/$SUBPATH")
|
||
|
||
# Пример: вытащим 2 ключа (замени на свои)
|
||
API_BASE_URL=$(echo "$JSON" | jq -r '.data.data.API_BASE_URL')
|
||
|
||
if [ -z "$API_BASE_URL" ] || [ "$API_BASE_URL" = "null" ]; then
|
||
echo "ERROR: API_BASE_URL is missing in Vault at $VAULT_KV_PATH"
|
||
exit 1
|
||
fi
|
||
|
||
# Экспортируем в env для следующих шагов:
|
||
echo "API_BASE_URL=$API_BASE_URL" >> "$GITHUB_ENV"
|
||
|
||
- name: Verify secrets loaded (safe)
|
||
run: |
|
||
# НЕ печатаем сами значения!
|
||
echo "API_BASE_URL loaded: $([ -n "$API_BASE_URL" ] && echo yes || echo no)"
|
||
|
||
- name: Install deps
|
||
run: |
|
||
corepack enable
|
||
pnpm -v || true
|
||
pnpm install
|
||
|
||
- name: Build
|
||
env:
|
||
API_BASE_URL: ${{ env.API_BASE_URL }}
|
||
SENTRY_DSN: ${{ env.SENTRY_DSN }}
|
||
run: pnpm build |