diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 9a7eb44..1cf942d 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -4,7 +4,6 @@ on: push: branches: [main] pull_request: - workflow_dispatch: permissions: contents: read @@ -18,7 +17,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 55 env: - CGO_ENABLED: '0' + CI_RUN_ID: ${{ gitea.run_id }} steps: - uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: @@ -27,68 +26,12 @@ jobs: with: go-version-file: go.mod cache: false - - name: Install frontend dependencies + - name: Check CI behavior and project run: | - corepack enable - corepack prepare pnpm@12.11.2 --activate - pnpm -C web install --frozen-lockfile --registry=https://registry.npmjs.org - - name: Check and build frontend - run: | - pnpm -C web lint:check - pnpm -C web typecheck - pnpm -C web test - pnpm -C web build - pnpm -C web build:demo - - name: Check backend - run: | - go vet -tags dev ./... - go test ./internal/... - go test -tags dev ./web ./cmd/rawmark - go vet ./... - go test ./web ./cmd/rawmark - - name: Test filesystem permissions as an unprivileged user - run: | - for package in vault watch; do - go test -c -o "/tmp/rawmark-$package.test" "./internal/$package" - (cd "internal/$package" && runuser -u node -- "/tmp/rawmark-$package.test" -test.v) - done - - name: Build platform packages and smoke-test Linux amd64 - run: | - mkdir -p package/licenses downloads - cp LICENSE package/ - cp web/LICENSE package/licenses/vue3-starter-MIT.txt - cp web/src/common/appearance/fonts/*-OFL.txt package/licenses/ - cp web/src/common/appearance/fonts/maple/LICENSE.txt package/licenses/Maple-Mono-OFL.txt - for target in linux/amd64 linux/arm64 windows/amd64 darwin/arm64 darwin/amd64; do - export GOOS="${target%/*}" GOARCH="${target#*/}" - extension='' - if [ "$GOOS" = windows ]; then extension='.exe'; fi - rm -f package/rawmark package/rawmark.exe - go vet ./... - go build -trimpath -ldflags="-s -w -X main.releaseVersion=$(cat VERSION)" -o "package/rawmark$extension" ./cmd/rawmark - if [ "$target" = linux/amd64 ]; then - python3 scripts/smoke-release.py package/rawmark - fi - python3 scripts/package-release.py "$GOOS" "$GOARCH" - done - - name: Check upload sizes and generate checksums - run: | - python3 - <<'PY' - import hashlib - from pathlib import Path - - archives = sorted(Path('downloads').glob('rawmark_*')) - if len(archives) != 5: - raise SystemExit(f'Expected five platform packages, found {len(archives)}') - checksums = [] - for archive in archives: - size = archive.stat().st_size - print(f'{archive.name}: {size:,} bytes') - if size >= 90_000_000: - raise SystemExit(f'{archive.name} exceeds the 90 MB upload budget (Cloudflare limit: 100 MB)') - checksums.append(f'{hashlib.file_digest(archive.open("rb"), "sha256").hexdigest()} {archive.name}\n') - Path('downloads/SHA256SUMS').write_text(''.join(checksums)) - PY + python3 -m unittest discover -s scripts/tests -v + sh scripts/ci-check.sh development + - name: Package and smoke-test Linux amd64 + run: sh scripts/ci-package.sh development - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: linux-amd64 @@ -96,50 +39,34 @@ jobs: compression-level: 0 if-no-files-found: error retention-days: 7 - - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: linux-arm64 - path: downloads/*_linux_arm64.tar.gz - compression-level: 0 - if-no-files-found: error - retention-days: 7 - - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: windows-amd64 - path: downloads/*_windows_amd64.zip - compression-level: 0 - if-no-files-found: error - retention-days: 7 - - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: darwin-arm64 - path: downloads/*_darwin_arm64.tar.gz - compression-level: 0 - if-no-files-found: error - retention-days: 7 - - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: darwin-amd64 - path: downloads/*_darwin_amd64.tar.gz - compression-level: 0 - if-no-files-found: error - retention-days: 7 - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: checksums - path: downloads/SHA256SUMS + path: | + downloads/SHA256SUMS + downloads/build.json if-no-files-found: error retention-days: 7 - docker-smoke: + image: needs: check-and-package + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' runs-on: docker - timeout-minutes: 15 + timeout-minutes: 20 + env: + CI_RUN_ID: ${{ gitea.run_id }} + CI_RUN_ATTEMPT: ${{ gitea.run_attempt }} + CI_RESOURCE_LABEL: io.rawmark.ci.run=dev-${{ gitea.run_id }}-${{ gitea.run_attempt }} + TEMP_IMAGE: rawmark-ci:${{ gitea.sha }}-${{ gitea.run_id }}-${{ gitea.run_attempt }} + DOCKER_CONFIG: /tmp/rawmark-docker-auth + outputs: + image: ${{ steps.publish.outputs.image }} + version: ${{ steps.publish.outputs.version }} defaults: run: shell: sh steps: - - name: Install CI action and smoke-test runtimes + - name: Install CI runtimes run: apk add --no-cache nodejs python3 - uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: @@ -152,27 +79,63 @@ jobs: with: name: checksums path: downloads - - name: Verify the tested binary archive - run: | - python3 - <<'PY' - import hashlib - from pathlib import Path - - expected = {line.split()[1]: line.split()[0] for line in Path('downloads/SHA256SUMS').read_text().splitlines()} - archive = Path(f'downloads/rawmark_{Path("VERSION").read_text().strip()}_linux_amd64.tar.gz') - with archive.open('rb') as source: - assert hashlib.file_digest(source, 'sha256').hexdigest() == expected[archive.name] - PY - mkdir -p image/linux/amd64 image/data - tar -xzf "downloads/rawmark_$(cat VERSION)_linux_amd64.tar.gz" -C image/linux/amd64 - - name: Build and test the isolated container image - env: - COMMIT_SHA: ${{ gitea.sha }} - RUN_ID: ${{ gitea.run_id }} - RUN_ATTEMPT: ${{ gitea.run_attempt }} + - name: Verify, build and smoke-test the exact binary run: | set -eu - image="rawmark-ci:$COMMIT_SHA-$RUN_ID-$RUN_ATTEMPT" - docker build --build-arg TARGETARCH=amd64 --tag "$image" -f deploy/Dockerfile.release image - trap 'docker image rm "$image"' EXIT - python3 scripts/smoke-docker.py "$image" --client-container "$(hostname)" + python3 scripts/release.py prepare-image + docker build --provenance=false --build-arg TARGETARCH=amd64 --tag "$TEMP_IMAGE" \ + --label "org.opencontainers.image.revision=${{ gitea.sha }}" \ + --label "org.opencontainers.image.version=$(cat VERSION)" \ + -f deploy/Dockerfile.release image + python3 scripts/smoke-docker.py "$TEMP_IMAGE" --client-container "$(hostname)" \ + --resource-label "$CI_RESOURCE_LABEL" + - name: Publish immutable development image + id: publish + env: + GITEA_RELEASE_TOKEN: ${{ secrets.RAWMARK_GITEA_TOKEN }} + run: | + set -eu + mkdir -m 700 "$DOCKER_CONFIG" + python3 scripts/release.py promote-development "$TEMP_IMAGE" + - name: Clean only this attempt's resources and credentials + if: always() + run: | + python3 scripts/ci-cleanup.py "$CI_RESOURCE_LABEL" --client-container "$(hostname)" --image "$TEMP_IMAGE" + rm -rf "$DOCKER_CONFIG" + + deploy-development: + needs: image + if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' + runs-on: docker + timeout-minutes: 15 + container: + image: docker:29-cli + volumes: + - /docker/main/rawmark-dev:/docker/main/rawmark-dev + env: + GITEA_API_URL: ${{ gitea.server_url }}/api/v1 + GITEA_RELEASE_TOKEN: ${{ secrets.RAWMARK_GITEA_TOKEN }} + DOCKER_CONFIG: /tmp/rawmark-docker-auth + DEPLOY_IMAGE: ${{ needs.image.outputs.image }} + DEPLOY_VERSION: ${{ needs.image.outputs.version }} + DEPLOY_COMMIT: ${{ gitea.sha }} + defaults: + run: + shell: sh + steps: + - name: Install deployment runtimes + run: apk add --no-cache nodejs python3 docker-cli-compose + - uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - name: Deploy only the independent development instance + run: | + set -eu + mkdir -m 700 "$DOCKER_CONFIG" + printf '%s' "$GITEA_RELEASE_TOKEN" | docker login git.134333.xyz --username eezd --password-stdin + python3 scripts/deploy.py development --directory /docker/main/rawmark-dev \ + --image "$DEPLOY_IMAGE" --commit "$DEPLOY_COMMIT" --version "$DEPLOY_VERSION" \ + --client-container "$(hostname)" + - name: Remove job credentials + if: always() + run: rm -rf "$DOCKER_CONFIG" diff --git a/.gitea/workflows/deploy-production.yml b/.gitea/workflows/deploy-production.yml new file mode 100644 index 0000000..bc8ed1c --- /dev/null +++ b/.gitea/workflows/deploy-production.yml @@ -0,0 +1,49 @@ +name: Deploy production manually + +on: + workflow_dispatch: + inputs: + version: + description: Completed formal release version (X.Y.Z) + required: true + type: string + +permissions: + contents: read + +concurrency: + group: rawmark-production + cancel-in-progress: false + +jobs: + deploy: + if: gitea.ref == 'refs/heads/main' + runs-on: docker + timeout-minutes: 20 + container: + image: docker:29-cli + volumes: + - /docker/main/rawmark:/docker/main/rawmark + env: + GITEA_API_URL: ${{ gitea.server_url }}/api/v1 + GITEA_READ_TOKEN: ${{ gitea.token }} + RELEASE_VERSION: ${{ inputs.version }} + DOCKER_CONFIG: /tmp/rawmark-anonymous-docker + defaults: + run: + shell: sh + steps: + - name: Install deployment runtimes + run: apk add --no-cache nodejs python3 docker-cli-compose + - uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - name: Verify completed release, back up and deploy only RawMark + run: | + set -eu + mkdir -m 700 "$DOCKER_CONFIG" + python3 scripts/deploy.py production --directory /docker/main/rawmark \ + --version "$RELEASE_VERSION" --client-container "$(hostname)" + - name: Remove job configuration + if: always() + run: rm -rf "$DOCKER_CONFIG" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..daf1219 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,151 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: Version matching VERSION (X.Y.Z) + required: true + type: string + commit: + description: Full main commit SHA with successful development CI + required: true + type: string + +permissions: + contents: read + +concurrency: + group: rawmark-release + cancel-in-progress: false + +env: + GITEA_API_URL: ${{ gitea.server_url }}/api/v1 + CI_RUN_ID: ${{ gitea.run_id }} + +jobs: + build: + if: gitea.ref == 'refs/heads/main' + runs-on: ubuntu-latest + timeout-minutes: 55 + env: + GITEA_RELEASE_TOKEN: ${{ secrets.RAWMARK_GITEA_TOKEN }} + GITHUB_RELEASE_TOKEN: ${{ secrets.RAWMARK_GITHUB_TOKEN }} + RELEASE_VERSION: ${{ inputs.version }} + RELEASE_COMMIT: ${{ inputs.commit }} + outputs: + completed: ${{ steps.preflight.outputs.completed }} + steps: + - uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + ref: ${{ inputs.commit }} + fetch-depth: 0 + persist-credentials: false + - name: Validate source, permissions and existing release checkpoint + id: preflight + run: python3 scripts/release.py preflight "$RELEASE_VERSION" "$RELEASE_COMMIT" + - uses: https://github.com/actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + if: steps.preflight.outputs.reuse == 'false' + with: + go-version-file: go.mod + cache: false + - name: Check and build the five platform packages + if: steps.preflight.outputs.reuse == 'false' + run: | + python3 -m unittest discover -s scripts/tests -v + sh scripts/ci-check.sh release + sh scripts/ci-package.sh release + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: linux-amd64 + path: downloads/*_linux_amd64.tar.gz + compression-level: 0 + if-no-files-found: error + retention-days: 30 + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: linux-arm64 + path: downloads/*_linux_arm64.tar.gz + compression-level: 0 + if-no-files-found: error + retention-days: 30 + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: windows-amd64 + path: downloads/*_windows_amd64.zip + compression-level: 0 + if-no-files-found: error + retention-days: 30 + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: darwin-amd64 + path: downloads/*_darwin_amd64.tar.gz + compression-level: 0 + if-no-files-found: error + retention-days: 30 + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: darwin-arm64 + path: downloads/*_darwin_arm64.tar.gz + compression-level: 0 + if-no-files-found: error + retention-days: 30 + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: checksums + path: | + downloads/SHA256SUMS + downloads/build.json + if-no-files-found: error + retention-days: 30 + - uses: https://github.com/actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 + if: steps.preflight.outputs.reuse == 'false' + with: + name: demo + path: downloads/demo.zip + compression-level: 0 + if-no-files-found: error + retention-days: 30 + - name: Save immutable build checkpoint after artifact uploads + if: steps.preflight.outputs.reuse == 'false' + run: python3 scripts/release.py checkpoint + + publish: + needs: build + if: needs.build.outputs.completed == 'false' + runs-on: docker + timeout-minutes: 55 + container: + image: docker:29-cli + env: + GITEA_RELEASE_TOKEN: ${{ secrets.RAWMARK_GITEA_TOKEN }} + GITHUB_RELEASE_TOKEN: ${{ secrets.RAWMARK_GITHUB_TOKEN }} + CI_RESOURCE_LABEL: io.rawmark.ci.run=release-${{ gitea.run_id }}-${{ gitea.run_attempt }} + DOCKER_CONFIG: /tmp/rawmark-docker-auth + defaults: + run: + shell: sh + steps: + - name: Install publication runtimes + run: apk add --no-cache nodejs python3 git skopeo + - uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + ref: ${{ inputs.commit }} + fetch-depth: 0 + persist-credentials: false + - name: Publish the original checked artifacts to both services + run: | + set -eu + mkdir -m 700 "$DOCKER_CONFIG" + python3 scripts/release.py publish + - name: Clean only this attempt's test resources and credentials + if: always() + run: | + python3 scripts/ci-cleanup.py "$CI_RESOURCE_LABEL" --client-container "$(hostname)" + rm -rf "$DOCKER_CONFIG" diff --git a/.github/release-notes.md b/.github/release-notes.md index e58bb53..50104bc 100644 --- a/.github/release-notes.md +++ b/.github/release-notes.md @@ -12,7 +12,7 @@ Native downloads now cover five platforms: - Platform-specific disk space queries, temporary storage and restore-record publication support Windows backup/restore. - Windows paths reject device names, alternate data streams and filename aliases at note/import/backup boundaries. -- One release workflow tests each program on a native runner before packaging. Docker remains Linux amd64/arm64 and uses those tested programs. +- One Gitea release workflow checks the project and cross-builds all five targets. Linux amd64 runs native lifecycle tests; Windows, macOS and Linux arm64 remain unverified at runtime. Docker remains Linux amd64/arm64 and uses the same packaged programs. - Archives contain the CLI web server and licenses; no desktop GUI, installer or code signing is included. macOS may require manual approval for the unsigned download. ### Try or install @@ -22,8 +22,8 @@ Native downloads now cover five platforms: - Verify downloads using `SHA256SUMS`, then follow the [deployment guide](https://github.com/eezd/RawMark/blob/v0.1.1/docs/deployment.md). - [English README](https://github.com/eezd/RawMark/blob/v0.1.1/README.md) · [中文说明](https://github.com/eezd/RawMark/blob/v0.1.1/README.zh-CN.md). -Preserve your complete data directory and mount configuration when upgrading, and back up first. No database migration or cleanup SQL is required. Existing v0.1.0 downloads remain available. +Preserve your complete data directory and mount configuration when upgrading, and back up first. No historical cleanup SQL is required. This file is a release draft; availability depends on a completed formal release. --- -新增 Windows amd64、macOS Apple Silicon 和 Intel 原生程序,保留 Linux 双架构程序与 Docker 镜像。五个平台均在各自原生 runner 测试后打包,由同一个发布工作流完成。原生程序是网页服务端,不含桌面窗口、安装器或签名;macOS 首次运行可能需要手动允许。请先核对 SHA256SUMS,再参考部署指南。升级前备份并保留完整数据目录;无需执行数据库迁移或历史清理,v0.1.0 附件保持不变。 +新增 Windows amd64、macOS Apple Silicon 和 Intel 原生程序,保留 Linux 双架构程序与 Docker 镜像。同一个 Gitea 发布工作流完成检查与交叉构建;Linux amd64 执行原生生命周期测试,Windows、macOS 和 Linux arm64 尚未完成原生运行验收。原生程序是网页服务端,不含桌面窗口、安装器或签名;macOS 首次运行可能需要手动允许。请先核对 SHA256SUMS,再参考部署指南。升级前备份并保留完整数据目录,不重跑历史清理 SQL。此文件为发布草稿,产物是否可用以完整正式发布为准。 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 660866e..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,232 +0,0 @@ -name: Release - -on: - push: - tags: ['v*'] - -permissions: - contents: read - -concurrency: - group: rawmark-release - cancel-in-progress: false - -jobs: - check: - runs-on: ubuntu-24.04 - timeout-minutes: 30 - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Validate release tag - env: - RELEASE_TAG: ${{ github.ref_name }} - run: | - version="$(cat VERSION)" - [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] - test "$RELEASE_TAG" = "v$version" - - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 - with: - node-version: '24' - - name: Install frontend dependencies - run: | - corepack enable - corepack prepare pnpm@12.11.2 --activate - pnpm -C web install --frozen-lockfile --registry=https://registry.npmjs.org - - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 - with: - go-version-file: go.mod - - name: Check and build - run: | - pnpm -C web lint:check - pnpm -C web typecheck - pnpm -C web test - pnpm -C web build - pnpm -C web build:demo - go vet -tags dev ./... - go test ./internal/... - go test -tags dev ./web ./cmd/rawmark - - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: frontend - path: web/dist - if-no-files-found: error - retention-days: 3 - - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 - with: - path: web/dist-demo - - native: - needs: check - strategy: - fail-fast: false - max-parallel: 2 - matrix: - include: - - os: linux - arch: amd64 - runner: ubuntu-24.04 - extension: '' - - os: linux - arch: arm64 - runner: ubuntu-24.04-arm - extension: '' - - os: windows - arch: amd64 - runner: windows-2025 - extension: '.exe' - - os: darwin - arch: arm64 - runner: macos-15 - extension: '' - - os: darwin - arch: amd64 - runner: macos-15-intel - extension: '' - runs-on: ${{ matrix.runner }} - timeout-minutes: 30 - defaults: - run: - shell: bash - env: - CGO_ENABLED: '0' - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 - with: - go-version-file: go.mod - - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 - with: - name: frontend - path: web/dist - - name: Build and smoke-test native binary - env: - EXE: ${{ matrix.extension }} - run: | - mkdir -p package/licenses - go build -trimpath -ldflags="-s -w -X main.releaseVersion=$(cat VERSION)" -o "package/rawmark$EXE" ./cmd/rawmark - go vet ./... - go test ./internal/... ./cmd/rawmark ./web - python scripts/smoke-release.py "package/rawmark$EXE" - - name: Package download - env: - ARCH: ${{ matrix.arch }} - TARGET_OS: ${{ matrix.os }} - run: | - cp LICENSE package/ - cp web/LICENSE package/licenses/vue3-starter-MIT.txt - cp web/src/common/appearance/fonts/*-OFL.txt package/licenses/ - cp web/src/common/appearance/fonts/maple/LICENSE.txt package/licenses/Maple-Mono-OFL.txt - mkdir downloads - python scripts/package-release.py "$TARGET_OS" "$ARCH" - - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 - with: - name: native-${{ matrix.os }}-${{ matrix.arch }} - path: downloads/* - if-no-files-found: error - retention-days: 3 - - image: - needs: native - runs-on: ubuntu-24.04 - timeout-minutes: 20 - permissions: - contents: read - packages: write - outputs: - digest: ${{ steps.build.outputs.digest }} - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 - with: - pattern: native-linux-* - path: downloads - merge-multiple: true - - name: Prepare tested binaries - run: | - mkdir -p image/linux/amd64 image/linux/arm64 image/data - for arch in amd64 arm64; do - tar -xzf "downloads/rawmark_$(cat VERSION)_linux_$arch.tar.gz" -C "image/linux/$arch" - done - - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - - uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Publish version image - id: build - uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 - with: - context: image - file: deploy/Dockerfile.release - platforms: linux/amd64,linux/arm64 - push: true - tags: ghcr.io/eezd/rawmark:${{ github.ref_name }} - labels: | - org.opencontainers.image.source=https://github.com/eezd/RawMark - org.opencontainers.image.version=${{ github.ref_name }} - org.opencontainers.image.revision=${{ github.sha }} - org.opencontainers.image.licenses=MIT - - name: Smoke-test packaged image - env: - RELEASE_TAG: ${{ github.ref_name }} - run: | - image="ghcr.io/eezd/rawmark:$RELEASE_TAG" - test "$(docker run --rm "$image" --version)" = "RawMark $(cat VERSION)" - trap 'docker rm -f rawmark-smoke; docker volume rm rawmark-smoke-data' EXIT - docker run -d --name rawmark-smoke -v rawmark-smoke-data:/data -p 127.0.0.1:21876:8080 "$image" - for attempt in {1..60}; do - status="$(docker inspect --format '{{.State.Health.Status}}' rawmark-smoke)" - if [ "$status" = healthy ]; then break; fi - if [ "$status" = unhealthy ]; then docker logs rawmark-smoke; exit 1; fi - sleep 1 - done - test "$status" = healthy - test "$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:21876/api/v1/tree)" = 401 - docker exec rawmark-smoke /rawmark healthcheck - - pages: - needs: image - runs-on: ubuntu-24.04 - timeout-minutes: 10 - permissions: - contents: read - pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - steps: - - uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 - - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 - id: deployment - - release: - needs: [image, pages] - runs-on: ubuntu-24.04 - timeout-minutes: 10 - permissions: - contents: write - packages: write - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 - with: - pattern: native-* - path: downloads - merge-multiple: true - - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1 - - uses: docker/login-action@81c6f93d4bc991e510b342a00b419b3bb4efc5c6 # v4.7.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Publish release and stable image tags - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ github.ref_name }} - IMAGE_DIGEST: ${{ needs.image.outputs.digest }} - run: | - (cd downloads && sha256sum *.tar.gz *.zip > SHA256SUMS) - gh release create "$RELEASE_TAG" downloads/* --verify-tag --title "RawMark $RELEASE_TAG" --notes-file .github/release-notes.md --latest - docker buildx imagetools create --tag "ghcr.io/eezd/rawmark:$(cat VERSION)" --tag ghcr.io/eezd/rawmark:latest "ghcr.io/eezd/rawmark@$IMAGE_DIGEST"