name: Release actions on: push: tags: - 'v*' env: REGISTRY: ghcr.io IMAGE_NAME_DEPS: ${{ github.repository }}/opendht-deps IMAGE_NAME_DEPS_NOBLE: ${{ github.repository }}/opendht-deps-noble IMAGE_NAME: ${{ github.repository }}/opendht IMAGE_NAME_NOBLE: ${{ github.repository }}/opendht-noble IMAGE_NAME_DEPS_LLVM: ${{ github.repository }}/opendht-deps-llvm IMAGE_NAME_LLVM: ${{ github.repository }}/opendht-llvm IMAGE_NAME_DHTNODE: ${{ github.repository }}/dhtnode IMAGE_NAME_ALPINE: ${{ github.repository }}/opendht-alpine IMAGE_NAME_ALPINE_DEPS: ${{ github.repository }}/opendht-deps-alpine jobs: nodejs-package: name: Build and verify Node.js package uses: ./.github/workflows/nodejs-package.yml permissions: contents: read packages: read python-wheels: name: Build Python wheels uses: ./.github/workflows/python-wheels.yml permissions: contents: read build-and-push-deps-image: name: Dependency Docker image runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DEPS }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileDeps platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-deps-image-noble: name: Dependency Docker image (Ubuntu 24.04) runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DEPS_NOBLE }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileDepsNoble platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-image: name: OpenDHT Docker image runs-on: ubuntu-latest needs: build-and-push-deps-image permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/Dockerfile platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-image-noble: name: OpenDHT Docker image (Ubuntu 24.04) runs-on: ubuntu-latest needs: build-and-push-deps-image-noble permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_NOBLE }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileNoble platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-deps-image-llvm: name: Dependency Docker image (LLVM) runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DEPS_LLVM }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileDepsLlvm platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-image-llvm: name: OpenDHT Docker image (LLVM) runs-on: ubuntu-latest needs: build-and-push-deps-image-llvm permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_LLVM }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileLlvm platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-image-dhtnode: name: dhtnode Docker image runs-on: ubuntu-latest needs: build-and-push-image permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_DHTNODE }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileDhtnode platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-image-alpine-deps: name: Alpine Deps Docker image runs-on: ubuntu-latest permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_ALPINE_DEPS }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileDepsAlpine platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-and-push-image-alpine: name: Alpine Docker image runs-on: ubuntu-latest needs: build-and-push-image-alpine-deps permissions: contents: read packages: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_ALPINE }} - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . file: docker/DockerfileAlpine platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-windows-msi: name: Build Windows MSI Installer runs-on: windows-latest env: VCPKG_DISABLE_METRICS: "1" VCPKG_DEFAULT_TRIPLET: x64-windows VCPKG_INSTALLED_DIR: ${{ github.workspace }}\vcpkg_installed VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite permissions: contents: read steps: - name: Checkout repository uses: actions/checkout@v7 with: submodules: recursive - name: Set up vcpkg uses: lukka/run-vcpkg@v11 with: vcpkgJsonGlob: vcpkg.json vcpkgConfigurationJsonGlob: vcpkg-configuration.json - name: Set up MSVC developer environment uses: microsoft/setup-msbuild@v3 - name: Install WIX using .net tools run: | dotnet tool install --global wix --version 6.0.1 wix extension add --global WixToolset.UI.wixext/6.0.1 shell: pwsh - name: Cache vcpkg binary packages uses: actions/cache@v6 with: path: ${{ github.workspace }}/vcpkg-binary-cache key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }} restore-keys: | ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}- ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}- - name: Configure CMake for MSI shell: pwsh run: | mkdir build -ErrorAction SilentlyContinue cmake -B build ` -S . ` "-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` -DVCPKG_TARGET_TRIPLET=x64-windows ` -DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} ` -DVCPKG_MANIFEST_FEATURES=test ` -DCMAKE_BUILD_TYPE=Release ` -DOPENDHT_C=On ` -DOPENDHT_TOOLS=On ` -DOPENDHT_PYTHON=Off ` -DOPENDHT_DOCUMENTATION=OFF ` -DOPENDHT_PEER_DISCOVERY=On ` -DOPENDHT_PROXY_SERVER=On ` -DOPENDHT_PROXY_CLIENT=On ` -DOPENDHT_HTTP=On ` -DBUILD_TESTING=Off ` -DOPENDHT_CPACK=On ` -A x64 - name: Build with MSVC shell: pwsh run: | cmake --build build --config Release --parallel $([System.Environment]::ProcessorCount) # Copy vcpkg installed libraries to the build directory Copy-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}\x64-windows\lib\*.lib" -Destination "build" -Force Copy-Item -Path "${{ env.VCPKG_INSTALLED_DIR }}\x64-windows\bin\*.dll" -Destination "build" -Force - name: Package MSI with CPack shell: pwsh id: cpack_msi run: | cd build cpack -C Release -G WIX $msiFile = Get-ChildItem -Path . -Recurse -Filter *.msi | Select-Object -First 1 if ($msiFile) { $msiOutputPath = "opendht-installer.msi" # Standardized artifact name Copy-Item $msiFile.FullName -Destination $msiOutputPath echo "msi_path=$msiOutputPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append Write-Host "MSI created at build/$msiOutputPath" } else { Write-Error "MSI file not found after cpack execution!" exit 1 } - name: Upload MSI Artifact uses: actions/upload-artifact@v7 with: name: opendht-windows-msi path: build/${{ steps.cpack_msi.outputs.msi_path }} # Path to the MSI in the build directory retention-days: 7 build-windows-dhtnode: name: Build Windows dhtnode runs-on: windows-latest env: VCPKG_DISABLE_METRICS: "1" VCPKG_DEFAULT_TRIPLET: x64-windows-static-release VCPKG_INSTALLED_DIR: ${{ github.workspace }}\vcpkg_installed VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg-binary-cache,readwrite permissions: contents: read steps: - name: Checkout repository uses: actions/checkout@v7 with: submodules: recursive - name: Set up vcpkg uses: lukka/run-vcpkg@v11 with: vcpkgJsonGlob: vcpkg.json vcpkgConfigurationJsonGlob: vcpkg-configuration.json - name: Set up MSVC developer environment uses: microsoft/setup-msbuild@v3 - name: Cache vcpkg binary packages uses: actions/cache@v6 with: path: ${{ github.workspace }}/vcpkg-binary-cache key: ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}-${{ github.run_id }}-${{ github.run_attempt }} restore-keys: | ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}-${{ hashFiles('vcpkg.json', 'vcpkg-configuration.json', 'ports/**') }}- ${{ runner.os }}-vcpkg-binary-${{ env.VCPKG_DEFAULT_TRIPLET }}- - name: Configure CMake for Static Build shell: pwsh run: | mkdir build_static -ErrorAction SilentlyContinue cmake -B build_static ` -S . ` "-DCMAKE_TOOLCHAIN_FILE=$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` -DVCPKG_TARGET_TRIPLET=x64-windows-static-release ` -DVCPKG_INSTALLED_DIR=${{ env.VCPKG_INSTALLED_DIR }} ` -DVCPKG_MANIFEST_FEATURES=test ` -DCMAKE_BUILD_TYPE=Release ` -DBUILD_SHARED_LIBS=OFF ` -DOPENDHT_PROXY_CLIENT=ON ` -DOPENDHT_PROXY_SERVER=ON ` -DOPENDHT_C=ON ` -DOPENDHT_TOOLS=ON ` -DOPENDHT_DOCUMENTATION=OFF ` -DOPENDHT_PYTHON=OFF ` -DOPENDHT_PEER_DISCOVERY=ON ` -DOPENDHT_HTTP=ON ` -A x64 - name: Build Static dhtnode shell: pwsh run: | cmake --build build_static --config Release --parallel $([System.Environment]::ProcessorCount) - name: Upload Static dhtnode Artifact uses: actions/upload-artifact@v7 with: name: opendht-windows-dhtnode path: | build_static/**/*dhtnode.exe retention-days: 7 create-github-release: name: Create GitHub Release runs-on: ubuntu-latest needs: [build-windows-msi, build-windows-dhtnode, nodejs-package] permissions: contents: write steps: - name: Checkout repository uses: actions/checkout@v7 - name: Download Windows MSI artifact uses: actions/download-artifact@v8 with: name: opendht-windows-msi path: downloaded_artifacts/windows_msi - name: Download Static dhtnode artifact uses: actions/download-artifact@v8 with: name: opendht-windows-dhtnode path: downloaded_artifacts/static_dhtnode - name: Download npm archive uses: actions/download-artifact@v8 with: name: opendht-node-npm path: downloaded_artifacts/nodejs - name: Create Release id: create_release uses: softprops/action-gh-release@v3 with: draft: true prerelease: ${{ contains(github.ref_name, '-') }} files: | downloaded_artifacts/windows_msi/*.msi downloaded_artifacts/static_dhtnode/**/*dhtnode.exe downloaded_artifacts/nodejs/*.tgz publish-npm: name: Publish opendht to npm needs: create-github-release runs-on: ubuntu-26.04 environment: name: npm url: https://www.npmjs.com/package/opendht permissions: contents: read id-token: write steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: '24' registry-url: https://registry.npmjs.org/ package-manager-cache: false - uses: actions/download-artifact@v8 with: name: opendht-node-npm path: nodejs/dist - name: Publish verified archive working-directory: nodejs env: RELEASE_TAG: ${{ github.ref_name }} run: | dist_tag=latest if [[ "${RELEASE_TAG#v}" == *-* ]]; then dist_tag=next fi npm publish ./dist/*.tgz --access public --provenance --tag "$dist_tag" publish-pypi: name: Publish opendht to PyPI needs: [create-github-release, python-wheels] runs-on: ubuntu-latest environment: name: pypi url: https://pypi.org/p/opendht permissions: contents: read id-token: write steps: - uses: actions/download-artifact@v8 with: pattern: opendht-wheels-* path: dist merge-multiple: true - name: Publish wheels uses: pypa/gh-action-pypi-publish@release/v1 publish-crate: name: Publish opendht to crates.io needs: create-github-release runs-on: ubuntu-latest environment: name: crates-io url: https://crates.io/crates/opendht permissions: contents: read id-token: write steps: - uses: actions/checkout@v7 - uses: taiki-e/install-action@v2 with: tool: cargo-edit - name: Set crate version from release tag working-directory: rust env: RELEASE_TAG: ${{ github.ref_name }} run: cargo set-version "${RELEASE_TAG#v}" - name: Authenticate with crates.io id: auth uses: rust-lang/crates-io-auth-action@v1 - name: Publish crate working-directory: rust env: CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} run: cargo publish --allow-dirty