quality / commitlint (push) Skipped
CD / update-wiki (push) Failing after 7s
quality / changes (push) Successful in 4s
quality / docker-check (push) Skipped
quality / web (push) Failing after 38s
quality / api (push) Successful in 49s
CD / quality (push) Failing after 1m36s
CD / publish (push) Skipped
204 lines
8.2 KiB
YAML
204 lines
8.2 KiB
YAML
name: CD
|
||
|
||
on:
|
||
push:
|
||
branches: [main, master]
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
jobs:
|
||
quality:
|
||
uses: ./.gitea/workflows/quality.yaml
|
||
with:
|
||
is_pull_request: false
|
||
before_sha: ${{ github.event.before }}
|
||
head_sha: ${{ github.sha }}
|
||
allow_registry_login: false
|
||
secrets:
|
||
ACTIONS_PAT: ${{ secrets.ACTIONS_PAT }}
|
||
|
||
update-wiki:
|
||
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout main repository
|
||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||
with:
|
||
fetch-depth: 2
|
||
- name: Check for changes in documentation
|
||
id: check_changes
|
||
run: |
|
||
set -euo pipefail
|
||
if ! git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
|
||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||
elif git diff HEAD~1 HEAD --quiet -- docs/Home.md; then
|
||
echo "changed=false" >> "$GITHUB_OUTPUT"
|
||
else
|
||
echo "changed=true" >> "$GITHUB_OUTPUT"
|
||
fi
|
||
- name: Update and push Wiki content
|
||
if: steps.check_changes.outputs.changed == 'true'
|
||
env:
|
||
# ACTIONS_PAT уже пишет git (tags/releases). GITEA_TOKEN — опциональный
|
||
# wiki-only PAT; если он задан без write, Gitea отвечает 404, не 403.
|
||
WIKI_TOKEN: ${{ secrets.ACTIONS_PAT || secrets.GITEA_TOKEN }}
|
||
# Не gitea.server_url: на runner это внутренний http://192.168.x.x:3000,
|
||
# а ROOT_URL = git.shx.one — git-receive-pack wiki тогда даёт 404.
|
||
GITEA_PUBLIC_URL: https://git.shx.one
|
||
REPO: ${{ gitea.repository }}
|
||
run: |
|
||
set -euo pipefail
|
||
if [ -z "${WIKI_TOKEN:-}" ]; then
|
||
echo "ACTIONS_PAT / GITEA_TOKEN is empty — cannot push wiki"
|
||
exit 1
|
||
fi
|
||
PUBLIC_URL="${GITEA_PUBLIC_URL%/}"
|
||
TOKEN_ENC="$(python3 -c 'import urllib.parse,os; print(urllib.parse.quote(os.environ["WIKI_TOKEN"], safe=""))')"
|
||
WIKI_URL="${PUBLIC_URL}/${REPO}.wiki.git"
|
||
# Gitea на неаутентифицированный wiki push отвечает 404, не 401 —
|
||
# extraHeader/ASKPASS не помогают: токен должен быть в URL с первого запроса.
|
||
AUTH_INSTEAD="url.https://oauth2:${TOKEN_ENC}@${PUBLIC_URL#https://}/.insteadOf=${PUBLIC_URL}/"
|
||
GIT_TERMINAL_PROMPT=0 git -c "${AUTH_INSTEAD}" clone "${WIKI_URL}" cdnmanager.wiki
|
||
cp docs/Home.md cdnmanager.wiki/Home.md
|
||
cd cdnmanager.wiki
|
||
git config user.name "Gitea Actions"
|
||
git config user.email "actions@gitea"
|
||
git add Home.md
|
||
if git diff --staged --quiet; then
|
||
echo "Wiki Home.md already up to date"
|
||
exit 0
|
||
fi
|
||
git commit -m "docs: Update Wiki from main repository"
|
||
GIT_TERMINAL_PROMPT=0 git -c "${AUTH_INSTEAD}" push origin HEAD
|
||
|
||
publish:
|
||
needs: [quality]
|
||
if: >-
|
||
always() &&
|
||
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') &&
|
||
needs.quality.result == 'success'
|
||
runs-on: ubuntu-latest
|
||
permissions:
|
||
contents: write
|
||
packages: write
|
||
releases: write
|
||
steps:
|
||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||
with:
|
||
fetch-depth: 0
|
||
fetch-tags: true
|
||
token: ${{ secrets.ACTIONS_PAT || gitea.token }}
|
||
persist-credentials: true
|
||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||
with:
|
||
node-version: "22"
|
||
- name: Export cache paths
|
||
run: sh scripts/ci/export-cache-env.sh
|
||
- id: pnpm-hash
|
||
run: echo "key=$(sha256sum pnpm-lock.yaml | awk '{print $1}')" >> "$GITHUB_OUTPUT"
|
||
- id: pnpm-cache
|
||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||
with:
|
||
path: |
|
||
${{ env.PNPM_STORE_DIR }}
|
||
${{ env.COREPACK_HOME }}
|
||
node_modules
|
||
apps/web/node_modules
|
||
apps/api/node_modules
|
||
packages/ui/node_modules
|
||
packages/shared/node_modules
|
||
packages/db/node_modules
|
||
key: pnpm-${{ runner.os }}-${{ steps.pnpm-hash.outputs.key }}
|
||
restore-keys: |
|
||
pnpm-${{ runner.os }}-
|
||
- name: Install release tooling
|
||
env:
|
||
PNPM_CACHE_HIT: ${{ steps.pnpm-cache.outputs.cache-hit }}
|
||
run: sh scripts/ci/pnpm-ci.sh
|
||
- name: Verify releasable commit messages
|
||
run: pnpm exec node scripts/commit/verify-release-commits.mjs
|
||
- name: Semantic release
|
||
run: pnpm exec semantic-release
|
||
env:
|
||
GITEA_URL: https://git.shx.one
|
||
GITEA_TOKEN: ${{ secrets.ACTIONS_PAT || gitea.token }}
|
||
- name: Detect new release
|
||
id: rel
|
||
run: |
|
||
set -euo pipefail
|
||
version=""
|
||
if [ -f .release-version ]; then
|
||
version="$(tr -d '[:space:]' < .release-version)"
|
||
echo "New release from semantic-release: $version"
|
||
else
|
||
git fetch --tags --force origin || true
|
||
tag="$(git tag --points-at HEAD --list 'v*.*.*' | sort -V | tail -n1 || true)"
|
||
if [ -n "${tag:-}" ]; then
|
||
version="${tag#v}"
|
||
echo "Reuse existing tag $tag on HEAD (release retry)"
|
||
fi
|
||
fi
|
||
if [ -n "${version:-}" ]; then
|
||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||
echo "released=true" >> "$GITHUB_OUTPUT"
|
||
else
|
||
echo "released=false" >> "$GITHUB_OUTPUT"
|
||
echo "No releasable commits — skipping image publish"
|
||
fi
|
||
- name: Set up Docker Buildx
|
||
if: steps.rel.outputs.released == 'true'
|
||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||
with:
|
||
name: cdnmanager
|
||
driver: docker-container
|
||
cleanup: false
|
||
- name: Prepare image metadata
|
||
if: steps.rel.outputs.released == 'true'
|
||
id: meta
|
||
run: |
|
||
set -euo pipefail
|
||
echo "version=${{ steps.rel.outputs.version }}" >> "$GITHUB_OUTPUT"
|
||
owner_lc="$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')"
|
||
echo "owner_lc=$owner_lc" >> "$GITHUB_OUTPUT"
|
||
short_sha="$(echo '${{ github.sha }}' | cut -c1-7)"
|
||
echo "short_sha=$short_sha" >> "$GITHUB_OUTPUT"
|
||
echo "build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
|
||
- name: Log in to Gitea Registry
|
||
if: steps.rel.outputs.released == 'true'
|
||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
|
||
with:
|
||
registry: git.shx.one
|
||
username: ${{ gitea.actor }}
|
||
password: ${{ secrets.ACTIONS_PAT }}
|
||
- name: Mirror base images into buildcache
|
||
if: steps.rel.outputs.released == 'true'
|
||
env:
|
||
REGISTRY: git.shx.one/${{ steps.meta.outputs.owner_lc }}
|
||
MIRROR_ENV_FILE: ${{ runner.temp }}/mirror-base.env
|
||
run: sh deploy/docker/mirror-base-images.sh
|
||
- name: Build and push images (bake)
|
||
if: steps.rel.outputs.released == 'true'
|
||
env:
|
||
REGISTRY: git.shx.one/${{ steps.meta.outputs.owner_lc }}
|
||
IMAGE_TAG: latest
|
||
VERSION: ${{ steps.meta.outputs.version }}
|
||
SHORT_SHA: ${{ steps.meta.outputs.short_sha }}
|
||
SHA_FULL: ${{ github.sha }}
|
||
BUILD_TIME: ${{ steps.meta.outputs.build_time }}
|
||
CACHE_REF_NODE: git.shx.one/${{ steps.meta.outputs.owner_lc }}/cdnmanager-buildcache:node-buildcache
|
||
BUILDX_BAKE_ENTITLEMENTS_FS: "0"
|
||
BUILDX_BAKE_FILE_RELATIVE_PATHS: "1"
|
||
MIRROR_ENV_FILE: ${{ runner.temp }}/mirror-base.env
|
||
working-directory: deploy/docker
|
||
run: |
|
||
set -euxo pipefail
|
||
if [ -f "${MIRROR_ENV_FILE}" ]; then
|
||
set -a
|
||
# shellcheck disable=SC1090
|
||
. "${MIRROR_ENV_FILE}"
|
||
set +a
|
||
fi
|
||
docker buildx bake --allow=fs.read="${{ github.workspace }}" \
|
||
-f docker-bake.hcl default --push
|