diff --git a/.github/scripts/prepare-consumer.sh b/.github/scripts/prepare-consumer.sh new file mode 100644 index 0000000..43372f2 --- /dev/null +++ b/.github/scripts/prepare-consumer.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -euo pipefail + +: "${PUMPKIN_CI_CONSUMER:?Set PUMPKIN_CI_CONSUMER to the temporary consumer directory}" +mkdir -p "$PUMPKIN_CI_CONSUMER/src/wasmWasiMain/kotlin/ci" + +cat > "$PUMPKIN_CI_CONSUMER/settings.gradle.kts" <<'EOF' +pluginManagement { + repositories { + maven { url = uri(providers.environmentVariable("PUMPKIN_CI_REPOSITORY").get()) } + gradlePluginPortal() + mavenCentral() + } +} + +rootProject.name = "pumpkin-ci-consumer" +EOF + +cat > "$PUMPKIN_CI_CONSUMER/build.gradle.kts" <<'EOF' +import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl + +plugins { + kotlin("multiplatform") version "2.4.0" + id("io.github.pumpkin-mc.plugin") version "0.1.0-dev" +} + +repositories { + maven { url = uri(providers.environmentVariable("PUMPKIN_CI_REPOSITORY").get()) } + mavenCentral() +} + +kotlin { + @OptIn(ExperimentalWasmDsl::class) + wasmWasi { + nodejs() + binaries.executable() + } +} + +pumpkin { + apiVersion.set("0.1.0-dev") + pluginClass.set("ci.SmokePlugin") +} +EOF + +cat > "$PUMPKIN_CI_CONSUMER/gradle.properties" <<'EOF' +kotlin.daemon.jvmargs=-Xmx2g +EOF + +cat > "$PUMPKIN_CI_CONSUMER/src/wasmWasiMain/kotlin/ci/SmokePlugin.kt" <<'EOF' +package ci + +import plugin.PluginMetadata +import plugin.PumpkinPlugin + +class SmokePlugin : PumpkinPlugin() { + override fun metadata() = PluginMetadata( + name = "ci-smoke-plugin", + version = "0.1.0", + authors = listOf("Pumpkin"), + description = "Verifies consumer compilation with the generated plugin factory.", + dependencies = emptyList(), + permissions = emptyList(), + ) +} +EOF diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa6fc1d..5f4f19e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,7 @@ name: Main on: push: + branches: [master] pull_request: workflow_dispatch: workflow_run: @@ -10,13 +11,20 @@ on: - "Update WIT" permissions: - contents: write - pull-requests: write + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: main: - name: Build, test, and release + name: Build API and verify consumer + if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success' runs-on: ubuntu-latest + env: + PUMPKIN_CI_REPOSITORY: ${{ runner.temp }}/pumpkin-maven + PUMPKIN_CI_CONSUMER: ${{ runner.temp }}/pumpkin-consumer steps: - name: Checkout uses: actions/checkout@v6 @@ -26,18 +34,44 @@ jobs: - name: Set up Java/Kotlin uses: actions/setup-java@v6 with: - distribution: liberica + distribution: temurin java-version: "25" - name: Set up Gradle uses: gradle/actions/setup-gradle@v6 + with: + # PRs reuse the default-branch cache without updating it. + cache-read-only: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }} - - name: Cache Tools + - name: Prepare consumer fixture + run: bash .github/scripts/prepare-consumer.sh + + - name: Cache binding generator uses: actions/cache@v6 with: - path: tools - key: ${{ runner.os }}-${{ runner.arch }}-tools + path: api/tools + # GitHub scopes writes by ref; the hash prevents reuse after tool configuration changes. + key: ${{ runner.os }}-${{ runner.arch }}-wit-bindgen-${{ hashFiles('api/build.gradle.kts') }} - - name: Build example plugin to test + - name: Cache consumer tools + id: consumer-tools + uses: actions/cache@v6 + with: + path: ${{ env.PUMPKIN_CI_CONSUMER }}/build/tools + key: ${{ runner.os }}-${{ runner.arch }}-consumer-tools-${{ hashFiles('gradle-plugin/src/main/kotlin/io/github/pumpkinmc/gradle/PumpkinPlugin.kt') }} + + - name: Check and publish development packages run: | - ./gradlew build --no-daemon + ./gradlew :api:build :gradle-plugin:build :api:publishToMavenLocal :gradle-plugin:publishToMavenLocal \ + -Dmaven.repo.local="$PUMPKIN_CI_REPOSITORY" --build-cache --no-daemon + + - name: Build and validate consumer component + env: + CONSUMER_TOOLS_CACHE_HIT: ${{ steps.consumer-tools.outputs.cache-hit }} + run: | + args=() + # The installer will download again on a fresh runner otherwise + if [[ "$CONSUMER_TOOLS_CACHE_HIT" == "true" ]]; then + args+=(--exclude-task installWasmTools) + fi + ./gradlew -p "$PUMPKIN_CI_CONSUMER" build --build-cache --no-daemon "${args[@]}"