Build and Release #58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Product release CI (java-chains release repo; formerly web-chains). | |
| # Backend: Java-Chains/chains | SPA: in-tree java-chains-web-element (Vue Element Plus) | |
| name: Build and Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Release version without leading v (e.g. 2.0.0-beta3)" | |
| required: true | |
| type: string | |
| source_ref: | |
| description: "Source ref in Java-Chains/chains (tag, branch, or commit). Defaults to v<version>" | |
| required: false | |
| type: string | |
| publish: | |
| description: "Publish the GitHub Release immediately (skip draft). Default: draft only." | |
| required: false | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| jobs: | |
| # ==================================================== | |
| # Job 0: 解析发布元信息 | |
| # ==================================================== | |
| resolve_release_meta: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release_version: ${{ steps.meta.outputs.release_version }} | |
| release_tag: ${{ steps.meta.outputs.release_tag }} | |
| source_ref: ${{ steps.meta.outputs.source_ref }} | |
| is_prerelease: ${{ steps.meta.outputs.is_prerelease }} | |
| publish_release: ${{ steps.meta.outputs.publish_release }} | |
| docker_tags: ${{ steps.meta.outputs.docker_tags }} | |
| chains_dev_jars_repository: ${{ steps.manifest.outputs.chains_dev_jars_repository }} | |
| chains_dev_jars_ref: ${{ steps.manifest.outputs.chains_dev_jars_ref }} | |
| java_echo_generator_repository: ${{ steps.manifest.outputs.java_echo_generator_repository }} | |
| java_echo_generator_ref: ${{ steps.manifest.outputs.java_echo_generator_ref }} | |
| java_memshell_generator_repository: ${{ steps.manifest.outputs.java_memshell_generator_repository }} | |
| java_memshell_generator_ref: ${{ steps.manifest.outputs.java_memshell_generator_ref }} | |
| chains_config_repository: ${{ steps.manifest.outputs.chains_config_repository }} | |
| chains_config_ref: ${{ steps.manifest.outputs.chains_config_ref }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Resolve Release Metadata | |
| id: meta | |
| shell: bash | |
| run: | | |
| VERSION_INPUT="${{ inputs.version }}" | |
| VERSION="${VERSION_INPUT#v}" | |
| if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then | |
| echo "Invalid version: $VERSION_INPUT" | |
| echo "Use SemVer, for example: 2.0.0 or 2.0.0-beta3" | |
| exit 1 | |
| fi | |
| RELEASE_TAG="v$VERSION" | |
| SOURCE_REF="${{ inputs.source_ref }}" | |
| if [ -z "$SOURCE_REF" ]; then | |
| SOURCE_REF="$RELEASE_TAG" | |
| fi | |
| if [[ "$VERSION" == *-* ]]; then | |
| IS_PRERELEASE="true" | |
| else | |
| IS_PRERELEASE="false" | |
| fi | |
| # workflow_dispatch boolean → string "true"/"false"; default draft. | |
| PUBLISH_INPUT="${{ inputs.publish }}" | |
| if [ "$PUBLISH_INPUT" = "true" ]; then | |
| PUBLISH_RELEASE="true" | |
| else | |
| PUBLISH_RELEASE="false" | |
| fi | |
| echo "release_version=$VERSION" >> "$GITHUB_OUTPUT" | |
| echo "release_tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT" | |
| echo "source_ref=$SOURCE_REF" >> "$GITHUB_OUTPUT" | |
| echo "is_prerelease=$IS_PRERELEASE" >> "$GITHUB_OUTPUT" | |
| echo "publish_release=$PUBLISH_RELEASE" >> "$GITHUB_OUTPUT" | |
| { | |
| echo "docker_tags<<EOF" | |
| echo "javachains/javachains:${VERSION}" | |
| if [ "$IS_PRERELEASE" != "true" ]; then | |
| echo "javachains/javachains:latest" | |
| fi | |
| echo "EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Read Release Manifest | |
| id: manifest | |
| shell: bash | |
| run: | | |
| ruby <<'RUBY' | |
| require 'yaml' | |
| manifest = YAML.safe_load(File.read('.github/release-manifest.yml'), aliases: false) | |
| dependencies = manifest.fetch('dependencies') | |
| required = %w[ | |
| chains_dev_jars | |
| java_echo_generator | |
| java_memshell_generator | |
| chains_config | |
| ] | |
| File.open(ENV.fetch('GITHUB_OUTPUT'), 'a') do |out| | |
| required.each do |name| | |
| entry = dependencies[name] || abort("Missing dependency entry: #{name}") | |
| repository = entry['repository'].to_s.strip | |
| ref = entry['ref'].to_s.strip | |
| abort("Missing repository for #{name}") if repository.empty? | |
| abort("Missing ref for #{name}") if ref.empty? | |
| out.puts "#{name}_repository=#{repository}" | |
| out.puts "#{name}_ref=#{ref}" | |
| end | |
| end | |
| RUBY | |
| # ==================================================== | |
| # Job 1: 核心构建(适配 v2 模块与发行物) | |
| # ==================================================== | |
| build: | |
| needs: resolve_release_meta | |
| runs-on: ubuntu-latest | |
| outputs: | |
| source_sha: ${{ steps.source_revision.outputs.source_sha }} | |
| frontend_sha: ${{ steps.frontend.outputs.frontend_sha }} | |
| env: | |
| JAVA_VERSION: '8' | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: Java-Chains/chains | |
| ref: ${{ needs.resolve_release_meta.outputs.source_ref }} | |
| token: ${{ secrets.DEPENDENCY_REPO_TOKEN }} | |
| fetch-depth: 0 | |
| - name: Checkout Release Packaging Script | |
| uses: actions/checkout@v4 | |
| with: | |
| path: _release_ci | |
| sparse-checkout: | | |
| .github/scripts | |
| sparse-checkout-cone-mode: false | |
| clean: false | |
| - name: Capture Source Revision | |
| id: source_revision | |
| shell: bash | |
| run: | | |
| echo "source_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Resolve Element Frontend Revision | |
| id: frontend | |
| shell: bash | |
| run: | | |
| test -f java-chains-web-element/package.json | |
| test -f java-chains-web-element/pnpm-lock.yaml | |
| FRONTEND_SHA="$(git log -1 --format=%H -- java-chains-web-element)" | |
| FRONTEND_CT="$(git log -1 --format=%ct -- java-chains-web-element)" | |
| echo "frontend_sha=${FRONTEND_SHA}" >> "$GITHUB_OUTPUT" | |
| echo "SOURCE_DATE_EPOCH=${FRONTEND_CT}" >> "$GITHUB_ENV" | |
| echo "Using in-tree java-chains-web-element @ ${FRONTEND_SHA}" | |
| - name: Validate Source Version | |
| shell: bash | |
| run: | | |
| EXPECTED_VERSION="${{ needs.resolve_release_meta.outputs.release_version }}" | |
| POM_VERSION=$(sed -n '0,/<version>/s/.*<version>\([^<]*\)<\/version>.*/\1/p' pom.xml | head -n 1) | |
| if [ -z "$POM_VERSION" ]; then | |
| echo "Failed to read version from pom.xml" | |
| exit 1 | |
| fi | |
| if [ "$POM_VERSION" != "$EXPECTED_VERSION" ]; then | |
| echo "Version mismatch:" | |
| echo " source_ref: ${{ needs.resolve_release_meta.outputs.source_ref }}" | |
| echo " pom.xml: $POM_VERSION" | |
| echo " input: $EXPECTED_VERSION" | |
| echo "Please bump/tag the source repo first, or pass the correct source_ref." | |
| exit 1 | |
| fi | |
| - name: Clone Pinned Dependency Repositories | |
| env: | |
| DEPENDENCY_REPO_TOKEN: ${{ secrets.DEPENDENCY_REPO_TOKEN }} | |
| CHAINS_DEV_JARS_REPOSITORY: ${{ needs.resolve_release_meta.outputs.chains_dev_jars_repository }} | |
| CHAINS_DEV_JARS_REF: ${{ needs.resolve_release_meta.outputs.chains_dev_jars_ref }} | |
| JAVA_ECHO_GENERATOR_REPOSITORY: ${{ needs.resolve_release_meta.outputs.java_echo_generator_repository }} | |
| JAVA_ECHO_GENERATOR_REF: ${{ needs.resolve_release_meta.outputs.java_echo_generator_ref }} | |
| JAVA_MEMSHELL_GENERATOR_REPOSITORY: ${{ needs.resolve_release_meta.outputs.java_memshell_generator_repository }} | |
| JAVA_MEMSHELL_GENERATOR_REF: ${{ needs.resolve_release_meta.outputs.java_memshell_generator_ref }} | |
| CHAINS_CONFIG_REPOSITORY: ${{ needs.resolve_release_meta.outputs.chains_config_repository }} | |
| CHAINS_CONFIG_REF: ${{ needs.resolve_release_meta.outputs.chains_config_ref }} | |
| run: | | |
| mkdir -p release-deps | |
| clone_repo() { | |
| local repository="$1" | |
| local directory="$2" | |
| local ref="$3" | |
| local url="https://x-access-token:${DEPENDENCY_REPO_TOKEN}@github.com/${repository}.git" | |
| echo "Cloning ${repository} @ ${ref}" | |
| git clone "$url" "$directory" | |
| git -C "$directory" checkout "$ref" | |
| echo "Resolved $(git -C "$directory" rev-parse HEAD) for ${repository}" | |
| } | |
| clone_repo "$CHAINS_DEV_JARS_REPOSITORY" "release-deps/chains-dev-jars" "$CHAINS_DEV_JARS_REF" | |
| clone_repo "$JAVA_ECHO_GENERATOR_REPOSITORY" "release-deps/java-echo-generator" "$JAVA_ECHO_GENERATOR_REF" | |
| clone_repo "$JAVA_MEMSHELL_GENERATOR_REPOSITORY" "release-deps/java-memshell-generator" "$JAVA_MEMSHELL_GENERATOR_REF" | |
| clone_repo "$CHAINS_CONFIG_REPOSITORY" "release-deps/chains-config" "$CHAINS_CONFIG_REF" | |
| - name: Set up Temurin JDK ${{ env.JAVA_VERSION }} | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: 'temurin' | |
| java-version: ${{ env.JAVA_VERSION }} | |
| cache: 'maven' | |
| - name: Set up Maven | |
| uses: stCarolas/setup-maven@v5 | |
| with: | |
| maven-version: 3.9.6 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| - uses: pnpm/action-setup@v4 | |
| with: | |
| version: 9 | |
| - name: Cache Maven dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2/repository | |
| key: ${{ runner.os }}-maven-v2-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-maven-v2- | |
| ${{ runner.os }}-maven- | |
| - name: Clone and Install Dev Jars | |
| run: | | |
| ( | |
| cd release-deps/chains-dev-jars | |
| bash mvn_install.sh | |
| ) | |
| - name: Build and Install Generators | |
| run: | | |
| ( | |
| cd release-deps/java-echo-generator | |
| mvn clean install -DskipTests | |
| ) | |
| ( | |
| cd release-deps/java-memshell-generator | |
| mvn clean install -DskipTests | |
| ) | |
| - name: Build Ship Artifacts (Element SPA + CLI) | |
| run: | | |
| # Product SPA = java-chains-web-element (pnpm → generated-resources/static). | |
| # Prefer in-tree ship script from chains; fall back to release-repo copy. | |
| if [ ! -f scripts/frontend/package-java-chains-web-element.sh ]; then | |
| install -m 0755 _release_ci/.github/scripts/package-java-chains-web-element.sh \ | |
| scripts/frontend/package-java-chains-web-element.sh | |
| fi | |
| # ONE Maven invocation: second `mvn -am package` without -Pfrontend reuses | |
| # server target/ but a new maven.build.timestamp → Vector A session mismatch. | |
| # Product surface: server + java-chains-cli (no java-chains-sdk). | |
| mvn -pl java-chains-server,java-chains-cli -am clean package \ | |
| -DskipTests -Pfrontend,with-exploits \ | |
| -Dfrontend.working.directory="${PWD}/java-chains-web-element" \ | |
| -Dfrontend.package.script="${PWD}/scripts/frontend/package-java-chains-web-element.sh" | |
| - name: Prepare Base Artifacts | |
| run: | | |
| mkdir -p release_base | |
| VERSION="${{ needs.resolve_release_meta.outputs.release_version }}" | |
| pick_first() { | |
| local candidate | |
| for candidate in "$@"; do | |
| if [ -f "$candidate" ]; then | |
| printf '%s\n' "$candidate" | |
| return 0 | |
| fi | |
| done | |
| return 1 | |
| } | |
| # 1. Server Spring Boot fat jar (SPA embedded). Publish as java-chains.jar. | |
| SERVER_JAR="$(pick_first \ | |
| "java-chains-${VERSION}-exec.jar" \ | |
| "java-chains-server-${VERSION}-exec.jar" \ | |
| "java-chains-server/target/java-chains-server-${VERSION}-exec.jar" \ | |
| "java-chains-server/target/java-chains-${VERSION}-exec.jar" \ | |
| )" || true | |
| if [ -z "${SERVER_JAR:-}" ]; then | |
| SERVER_JAR="$(find . -maxdepth 2 -type f \( \ | |
| -name "java-chains-*-exec.jar" -o -name "java-chains-server-*-exec.jar" \ | |
| \) ! -name "*-sources.jar" ! -name "*-javadoc.jar" | sort | head -n 1 || true)" | |
| fi | |
| if [ -f "${SERVER_JAR:-}" ]; then | |
| echo "Found Server Jar: ${SERVER_JAR}" | |
| cp "$SERVER_JAR" release_base/java-chains.jar | |
| else | |
| echo "Error: java-chains server exec jar not found" | |
| find . -maxdepth 3 -type f -name "*.jar" | sort | head -n 80 | |
| exit 1 | |
| fi | |
| # 2. Product CLI fat jar (java-chains-cli). Keep a thin remote jar if present. | |
| CLI_JAR="$(pick_first \ | |
| "java-chains-cli/target/java-chains-cli-${VERSION}-jar-with-dependencies.jar" \ | |
| "java-chains-cli/target/java-chains-cli-${VERSION}.jar" \ | |
| )" || true | |
| if [ -z "${CLI_JAR:-}" ]; then | |
| CLI_JAR="$(find java-chains-cli/target -type f -name "java-chains-cli-*-jar-with-dependencies.jar" 2>/dev/null | sort | head -n 1 || true)" | |
| fi | |
| if [ -f "${CLI_JAR:-}" ]; then | |
| echo "Found CLI Jar: ${CLI_JAR}" | |
| cp "$CLI_JAR" release_base/java-chains-cli.jar | |
| else | |
| echo "Error: java-chains-cli fat jar not found" | |
| exit 1 | |
| fi | |
| CLI_REMOTE_JAR="$(pick_first \ | |
| "java-chains-cli-remote/target/java-chains-cli-remote-${VERSION}-jar-with-dependencies.jar" \ | |
| "java-chains-cli-remote/target/java-chains-cli-remote-${VERSION}.jar" \ | |
| )" || true | |
| if [ -f "${CLI_REMOTE_JAR:-}" ]; then | |
| echo "Found CLI remote Jar: ${CLI_REMOTE_JAR}" | |
| cp "$CLI_REMOTE_JAR" release_base/java-chains-cli-remote.jar | |
| fi | |
| # 3. Runtime config (plugins / third-libs / presets) | |
| cp -r release-deps/chains-config release_base/chains-config | |
| rm -rf release_base/chains-config/.git | |
| if [ -d chains-config ]; then | |
| # Overlay any in-tree config additions (e.g. presets) without wiping deps. | |
| cp -a chains-config/. release_base/chains-config/ 2>/dev/null || true | |
| rm -rf release_base/chains-config/.git | |
| fi | |
| # ── 源码防泄漏:销毁所有源码,确保 artifact 只含编译产物 ── | |
| - name: Purge Source Code | |
| if: always() | |
| run: | | |
| rm -rf release-deps | |
| rm -rf ~/.m2/repository | |
| if find release_base -type f \( \ | |
| -name "*.java" -o -name "*.go" -o -name "*.ts" -o -name "*.tsx" \ | |
| -o -name "*.vue" -o -name "*.jsx" -o -name "*.py" \ | |
| -o -name "*-sources.jar" -o -name "*-javadoc.jar" \ | |
| -o -name ".git" -o -name ".gitignore" \ | |
| -o -name "pom.xml" -o -name "package.json" -o -name "go.mod" \ | |
| \) | grep -q .; then | |
| echo "ERROR: Source code files detected in release artifacts!" | |
| find release_base -type f \( \ | |
| -name "*.java" -o -name "*.go" -o -name "*.ts" -o -name "*.tsx" \ | |
| -o -name "*.vue" -o -name "*.jsx" -o -name "*.py" \ | |
| -o -name "*-sources.jar" -o -name "*-javadoc.jar" \ | |
| -o -name ".git" -o -name ".gitignore" \ | |
| -o -name "pom.xml" -o -name "package.json" -o -name "go.mod" \ | |
| \) | |
| exit 1 | |
| fi | |
| find release_base -type d -name ".git" -exec rm -rf {} + 2>/dev/null || true | |
| echo "Artifact contents:" | |
| find release_base -type f | sort | |
| - name: Upload Base Artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: base-artifacts | |
| path: release_base/ | |
| # ==================================================== | |
| # Job 2: Create Release | |
| # ==================================================== | |
| create_release: | |
| needs: [ resolve_release_meta, build ] | |
| runs-on: ubuntu-latest | |
| # No actions/* uses: — avoids GitHub "GetResolveActionsDownloadInfo" 503 during Set up job. | |
| # Notes are generated inline; gh is preinstalled on ubuntu-latest. | |
| steps: | |
| - name: Create GitHub Release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| RELEASE_TAG="${{ needs.resolve_release_meta.outputs.release_tag }}" | |
| RELEASE_VERSION="${{ needs.resolve_release_meta.outputs.release_version }}" | |
| SOURCE_REF="${{ needs.resolve_release_meta.outputs.source_ref }}" | |
| SOURCE_SHA="${{ needs.build.outputs.source_sha }}" | |
| FRONTEND_SHA="${{ needs.build.outputs.frontend_sha }}" | |
| IS_PRERELEASE="${{ needs.resolve_release_meta.outputs.is_prerelease }}" | |
| PUBLISH_RELEASE="${{ needs.resolve_release_meta.outputs.publish_release }}" | |
| if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then | |
| echo "Release $RELEASE_TAG already exists, skip creation." | |
| exit 0 | |
| fi | |
| cat > release-notes.txt <<EOF | |
| Auto-generated release for version ${RELEASE_VERSION} | |
| Backend repository: Java-Chains/chains | |
| Backend ref: ${SOURCE_REF} | |
| Backend commit: ${SOURCE_SHA} | |
| Frontend: java-chains-web-element (Vue3 + Element Plus, in-tree) | |
| Frontend commit: ${FRONTEND_SHA} | |
| Artifacts: | |
| - java-chains-\${VERSION}.tar.gz — Server (SPA from java-chains-web-element) + chains-config | |
| - java-chains-\${VERSION}-<platform>.tar.gz|zip — Server + bundled JDK 8 | |
| - java-chains-cli-\${VERSION}.tar.gz — Product CLI fat jar + chains-config | |
| - Docker: javachains/javachains:${RELEASE_VERSION} | |
| EOF | |
| ARGS=( | |
| "$RELEASE_TAG" | |
| --title "Release $RELEASE_TAG" | |
| --repo "$GITHUB_REPOSITORY" | |
| --notes-file release-notes.txt | |
| ) | |
| # Default: draft. Set workflow input publish=true to publish immediately. | |
| if [ "$PUBLISH_RELEASE" != "true" ]; then | |
| ARGS+=(--draft) | |
| echo "Creating DRAFT release $RELEASE_TAG" | |
| else | |
| echo "Creating PUBLISHED release $RELEASE_TAG (publish=true)" | |
| fi | |
| if [ "$IS_PRERELEASE" = "true" ]; then | |
| ARGS+=(--prerelease) | |
| fi | |
| gh release create "${ARGS[@]}" | |
| # ==================================================== | |
| # Job 3: 矩阵打包 (Server + JDK) | |
| # ==================================================== | |
| bundle_assets: | |
| needs: [ resolve_release_meta, build, create_release ] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os_api: linux | |
| arch_api: x64 | |
| suffix: linux-amd64 | |
| ext: tar.gz | |
| - os_api: linux | |
| arch_api: aarch64 | |
| suffix: linux-aarch64 | |
| ext: tar.gz | |
| - os_api: windows | |
| arch_api: x64 | |
| suffix: windows-amd64 | |
| ext: zip | |
| - os_api: windows | |
| arch_api: arm64 | |
| suffix: windows-arm64 | |
| ext: zip | |
| - os_api: mac | |
| arch_api: x64 | |
| suffix: macos-intel | |
| ext: tar.gz | |
| - os_api: mac | |
| arch_api: aarch64 | |
| suffix: macos-m-series | |
| ext: tar.gz | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: base-artifacts | |
| path: base | |
| - name: Download JDK 8 | |
| run: | | |
| API_URL="https://api.adoptium.net/v3/binary/latest/8/ga/${{ matrix.os_api }}/${{ matrix.arch_api }}/jdk/hotspot/normal/eclipse" | |
| USE_AZUL="false" | |
| if [ "${{ matrix.os_api }}" = "mac" ] && [ "${{ matrix.arch_api }}" = "aarch64" ]; then | |
| USE_AZUL="true" | |
| fi | |
| if [ "${{ matrix.os_api }}" = "windows" ] && [ "${{ matrix.arch_api }}" = "arm64" ]; then | |
| API_URL="https://api.adoptium.net/v3/binary/latest/8/ga/windows/x64/jdk/hotspot/normal/eclipse" | |
| fi | |
| if [ "$USE_AZUL" = "true" ]; then | |
| AZUL_OS="${{ matrix.os_api }}" | |
| if [ "$AZUL_OS" = "mac" ]; then | |
| AZUL_OS="macos" | |
| fi | |
| API_URL="https://api.azul.com/zulu/download/community/v1.0/bundles/latest/binary/?jdk_version=8&os=$AZUL_OS&arch=${{ matrix.arch_api }}&bundle_type=jdk&ext=${{ matrix.ext }}" | |
| fi | |
| if [ "${{ matrix.ext }}" = "zip" ]; then | |
| curl -L "$API_URL" -o jdk_bundle.zip | |
| unzip -q jdk_bundle.zip -d jdk_extracted | |
| else | |
| curl -L "$API_URL" -o jdk_bundle.tar.gz | |
| mkdir jdk_extracted | |
| tar -xzf jdk_bundle.tar.gz -C jdk_extracted | |
| fi | |
| SUBDIR=$(ls jdk_extracted | head -n 1) | |
| mv "jdk_extracted/$SUBDIR" jdk_final | |
| if [ "${{ matrix.os_api }}" = "mac" ] && [ -d "jdk_final/Contents/Home" ]; then | |
| mv jdk_final/Contents/Home jdk_real | |
| rm -rf jdk_final | |
| mv jdk_real jdk_final | |
| fi | |
| - name: Create Distribution Structure | |
| run: | | |
| DIST_DIR="java-chains-${{ needs.resolve_release_meta.outputs.release_version }}-${{ matrix.suffix }}" | |
| mkdir -p "$DIST_DIR" | |
| cp base/java-chains.jar "$DIST_DIR/" | |
| cp -r base/chains-config "$DIST_DIR/" | |
| mv jdk_final "$DIST_DIR/jdk" | |
| echo "DIST_DIR=$DIST_DIR" >> "$GITHUB_ENV" | |
| - name: Generate Start Scripts | |
| run: | | |
| cd "${{ env.DIST_DIR }}" | |
| if [ "${{ matrix.os_api }}" != "windows" ]; then | |
| printf '%s\n' \ | |
| '#!/bin/bash' \ | |
| 'BASE_DIR=$(cd "$(dirname "$0")" && pwd)' \ | |
| 'cd "$BASE_DIR"' \ | |
| 'exec "$BASE_DIR/jdk/bin/java" -jar "$BASE_DIR/java-chains.jar"' \ | |
| > start.sh | |
| chmod +x start.sh | |
| else | |
| printf '%s\r\n' \ | |
| '@echo off' \ | |
| 'set "BASE_DIR=%~dp0"' \ | |
| 'cd /d "%BASE_DIR%"' \ | |
| '"%BASE_DIR%jdk\bin\java.exe" -jar "%BASE_DIR%java-chains.jar"' \ | |
| 'pause' \ | |
| > start.bat | |
| fi | |
| - name: Compress and Upload | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| RELEASE_TAG="${{ needs.resolve_release_meta.outputs.release_tag }}" | |
| ASSET_NAME="${{ env.DIST_DIR }}.${{ matrix.ext }}" | |
| if [ "${{ matrix.ext }}" = "zip" ]; then | |
| zip -r -q "$ASSET_NAME" "${{ env.DIST_DIR }}" | |
| else | |
| tar -czf "$ASSET_NAME" "${{ env.DIST_DIR }}" | |
| fi | |
| gh release upload "$RELEASE_TAG" "$ASSET_NAME" --clobber --repo "$GITHUB_REPOSITORY" | |
| # ==================================================== | |
| # Job 4: 上传通用包 / CLI / SDK | |
| # ==================================================== | |
| upload_standard_assets: | |
| needs: [ resolve_release_meta, build, create_release ] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: base-artifacts | |
| path: base | |
| - name: Create and Upload Assets | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| RELEASE_TAG="${{ needs.resolve_release_meta.outputs.release_tag }}" | |
| RELEASE_VERSION="${{ needs.resolve_release_meta.outputs.release_version }}" | |
| cd base | |
| tar -czvf "java-chains-${RELEASE_VERSION}.tar.gz" java-chains.jar chains-config | |
| gh release upload "$RELEASE_TAG" "java-chains-${RELEASE_VERSION}.tar.gz" --clobber --repo "$GITHUB_REPOSITORY" | |
| mkdir cli_dist | |
| cp java-chains-cli.jar cli_dist/ | |
| cp -r chains-config cli_dist/ | |
| if [ -f java-chains-cli-remote.jar ]; then | |
| cp java-chains-cli-remote.jar cli_dist/ | |
| fi | |
| tar -czvf "java-chains-cli-${RELEASE_VERSION}.tar.gz" -C cli_dist . | |
| gh release upload "$RELEASE_TAG" "java-chains-cli-${RELEASE_VERSION}.tar.gz" --clobber --repo "$GITHUB_REPOSITORY" | |
| # ==================================================== | |
| # Job 5: Docker Build | |
| # ==================================================== | |
| docker_build: | |
| needs: [ resolve_release_meta, build ] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: base-artifacts | |
| path: . | |
| - name: Prepare Docker context | |
| run: | | |
| # Docker image only needs the server jar + chains-config | |
| rm -f java-chains-cli.jar java-chains-cli-remote.jar | |
| test -f java-chains.jar | |
| test -d chains-config | |
| ls -la | |
| - uses: docker/setup-qemu-action@v3 | |
| - uses: docker/setup-buildx-action@v3 | |
| - uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USERNAME }} | |
| password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | |
| - uses: docker/build-push-action@v6 | |
| with: | |
| file: Dockerfile | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ needs.resolve_release_meta.outputs.docker_tags }} |