diff --git a/.github/workflows/file-hygiene.yml b/.github/workflows/file-hygiene.yml index edb8f9e9f..3aa1faa70 100644 --- a/.github/workflows/file-hygiene.yml +++ b/.github/workflows/file-hygiene.yml @@ -5,6 +5,51 @@ on: push: branches: [main] +permissions: + contents: read + jobs: lint: - uses: hyperledger-identus/.github/.github/workflows/lint-files.yml@f2c9e417fa46f69b015a9cdbaafdfb9e52e4ed60 # main + name: File Hygiene + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: stable + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Install hygiene tools + run: | + sudo apt-get update + sudo apt-get install -y shellcheck + go install github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@latest + python3 -m pip install --user yamllint + npm install --global markdownlint-cli2 + + - name: EditorConfig Checker + run: ~/go/bin/ec + + - name: ShellCheck + run: | + mapfile -t shell_files < <(git ls-files '*.sh') + if [ "${#shell_files[@]}" -gt 0 ]; then + shellcheck -S warning "${shell_files[@]}" + fi + + - name: markdownlint + run: markdownlint-cli2 "**/*.md" + + - name: yamllint + run: ~/.local/bin/yamllint . diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 47bedbe39..fec29e82b 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -104,9 +104,28 @@ jobs: run: | brew install --overwrite aarch64-unknown-linux-gnu + - uses: maxim-lobanov/setup-xcode@v1 + if: matrix.os-type == 'macos' + with: + xcode-version: '16.2' + + - name: "Install build dependencies (Linux)" + if: matrix.os-type == 'linux' + run: sudo apt-get update && sudo apt-get install build-essential -y + + - name: "Install Rust toolchain" + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o rustup-init.sh + sh rustup-init.sh -y --profile minimal --default-toolchain stable + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + export PATH="$HOME/.cargo/bin:$PATH" + rustc --version + cargo --version + - name: "Install Rust Targets" if: matrix.os-type == 'macos' run: | + export PATH="$HOME/.cargo/bin:$PATH" rustup target add armv7-linux-androideabi rustup target add i686-linux-android rustup target add aarch64-linux-android @@ -116,18 +135,10 @@ jobs: rustup target add aarch64-unknown-linux-gnu rustup target add x86_64-unknown-linux-gnu - - uses: maxim-lobanov/setup-xcode@v1 - if: matrix.os-type == 'macos' + - name: "Setup node" + uses: actions/setup-node@v4 with: - xcode-version: '16.2' - - - name: "Install rust toolchain (Linux)" - if: matrix.os-type == 'linux' - run: sudo apt install rustc build-essential -y - - - name: "Install rust toolchain (Macos)" - if: matrix.os-type == 'macos' - run: brew install rustup + node-version: '20' - name: "Install wasm-pack" run: cargo install wasm-pack @@ -141,6 +152,98 @@ jobs: - name: "Build Check All tests" run: ./gradlew allTests + - name: "Build package artifacts" + if: matrix.os-type == 'macos' + run: ./gradlew :apollo:assembleJsPackage :apollo:createSwiftPackage publishToMavenLocal --no-configuration-cache + + - name: "Smoke test npm package" + if: matrix.os-type == 'macos' + run: | + set -euo pipefail + PACK_DIR=$(mktemp -d) + TEST_DIR=$(mktemp -d) + npm pack ./apollo/build/packages/js --pack-destination "$PACK_DIR" >/dev/null + pushd "$TEST_DIR" >/dev/null + npm init -y >/dev/null + npm install "$PACK_DIR"/*.tgz >/dev/null + node -e "require('@hyperledger/identus-apollo'); console.log('npm smoke ok');" + popd >/dev/null + rm -rf "$PACK_DIR" "$TEST_DIR" + + - name: "Smoke test Maven packages" + if: matrix.os-type == 'macos' + run: | + set -euo pipefail + VERSION=$(sed -n 's/^version = *//p' gradle.properties | tr -d '[:space:]') + KOTLIN_VERSION=$(sed -n 's/^kotlin = "\(.*\)"/\1/p' gradle/libs.versions.toml | head -n1) + test -f "$HOME/.m2/repository/org/hyperledger/identus/apollo-jvm/$VERSION/apollo-jvm-$VERSION.jar" + test -f "$HOME/.m2/repository/org/hyperledger/identus/apollo-android/$VERSION/apollo-android-$VERSION.aar" + test -f "$HOME/.m2/repository/org/hyperledger/identus/apollo-iosarm64/$VERSION/apollo-iosarm64-$VERSION.klib" + + TEST_DIR=$(mktemp -d) + cat <<'EOF' > "$TEST_DIR/settings.gradle.kts" + rootProject.name = "apollo-jvm-smoke" + EOF + cat < "$TEST_DIR/build.gradle.kts" + plugins { + kotlin("jvm") version "$KOTLIN_VERSION" + application + } + repositories { mavenLocal(); mavenCentral() } + dependencies { implementation("org.hyperledger.identus:apollo-jvm:$VERSION") } + application { mainClass.set("MainKt") } + EOF + mkdir -p "$TEST_DIR/src/main/kotlin" + cat <<'EOF' > "$TEST_DIR/src/main/kotlin/Main.kt" + import org.hyperledger.identus.apollo.utils.KMMECSecp256k1PublicKey + + fun main() { + val bytes = ByteArray(33) { 0 } + bytes[0] = 0x02 + KMMECSecp256k1PublicKey(bytes) + println("maven smoke ok") + } + EOF + gradle -p "$TEST_DIR" run --no-daemon + rm -rf "$TEST_DIR" + + - name: "Smoke test Swift package" + if: matrix.os-type == 'macos' + run: | + set -euo pipefail + TEST_DIR=$(mktemp -d) + ln -s "${GITHUB_WORKSPACE}/apollo/build/packages/ApolloSwift/ApolloLibrary.xcframework" "$TEST_DIR/ApolloLibrary.xcframework" + cat < "$TEST_DIR/Package.swift" + // swift-tools-version: 5.9 + import PackageDescription + + let package = Package( + name: "ApolloSwiftSmoke", + platforms: [.iOS(.v13), .macOS(.v11)], + products: [ + .executable(name: "ApolloSwiftSmoke", targets: ["ApolloSwiftSmoke"]) + ], + targets: [ + .binaryTarget( + name: "ApolloLibrary", + path: "ApolloLibrary.xcframework" + ), + .executableTarget( + name: "ApolloSwiftSmoke", + dependencies: ["ApolloLibrary"] + ) + ] + ) + EOF + mkdir -p "$TEST_DIR/Sources/ApolloSwiftSmoke" + cat <<'EOF' > "$TEST_DIR/Sources/ApolloSwiftSmoke/main.swift" + import ApolloLibrary + + print("swift smoke ok") + EOF + swift build --package-path "$TEST_DIR" + rm -rf "$TEST_DIR" + - name: "Generate kover coverage report" run: ./gradlew koverHtmlReport koverXmlReport diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fe800385..ef1f473ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,6 +36,7 @@ jobs: ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.HYP_BOT_GPG_PASSWORD }} ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.OSSRH_USERNAME }} ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.OSSRH_PASSWORD }} + NPM_CONFIG_PROVENANCE: true steps: - name: Checkout specified branch @@ -109,6 +110,18 @@ jobs: if: ${{ inputs.release_ts }} run: ./gradlew :apollo:assembleJsPackage + - name: NPM publish smoke test + if: ${{ inputs.release_ts }} + run: | + set -euo pipefail + STAGE_DIR=./apollo/build/packages/js + [ -d "$STAGE_DIR" ] || { echo "::error::$STAGE_DIR does not exist" >&2; exit 1; } + PACK_DIR=$(mktemp -d) + npm pack "$STAGE_DIR" --pack-destination "$PACK_DIR" >/dev/null + tar -tzf "$PACK_DIR"/*.tgz | grep -q '^package/ed25519_bip32_wasm\.js$' \ + || { echo "::error::ed25519_bip32_wasm.js is missing from the npm tarball" >&2; tar -tzf "$PACK_DIR"/*.tgz >&2; exit 1; } + rm -rf "$PACK_DIR" + - name: Prepare Swift XCFramework if: ${{ inputs.release_swift }} run: | @@ -137,7 +150,7 @@ jobs: - name: NPM publish if: ${{ inputs.release_ts }} - run: ./gradlew :apollo:publishJsPackageToNpmjsRegistry + run: npm publish ./apollo/build/packages/js --access public - uses: crazy-max/ghaction-import-gpg@v6 id: import-gpg diff --git a/apollo/build.gradle.kts b/apollo/build.gradle.kts index 19885fa51..0ad7226ec 100644 --- a/apollo/build.gradle.kts +++ b/apollo/build.gradle.kts @@ -299,6 +299,11 @@ tasks.withType().configureEach { dependsOn("npmBip32Wasm") } +// Make the staged npm package complete even when publishing via the npm CLI. +tasks.named("assembleJsPackage") { + dependsOn("npmBip32Wasm") +} + val swiftPackageUpdateMinOSVersion = tasks.register("updateMinOSVersion") { group = "multiplatform-swift-package"