Switch to GitHub Actions (#1315)

This switches our builds over to GitHub Actions!

TODO:

* Add macOS/amd64 native-image builds; this isn't working right now
* Patch musl with security patches
* Add benchmark jobs over time

As part of this build, PRBs will now only run `./gradlew check` on Linux,
but other jobs can be run using slash commands, e.g. `[windows]`
to run `./gradle check` on Windows.
This commit is contained in:
Daniel Chao
2025-11-13 16:03:05 -08:00
committed by GitHub
parent ecf2d8ba33
commit f948ba2a20
26 changed files with 4238 additions and 2225 deletions

33
.github/jobs/BuildJavaExecutableJob.pkl vendored Normal file
View File

@@ -0,0 +1,33 @@
extends "GradleJob.pkl"
import "@gha/actions/Artifact.pkl"
import "@gha/actions/Common.pkl"
// Keep this in sync with projects that build java executables
local projects: List<String> = List("pkl-doc", "pkl-cli", "pkl-codegen-java", "pkl-codegen-kotlin")
local command =
new Listing<String> {
"./gradlew"
module.gradleArgs
for (project in projects) {
// NOTE: `build` doesn't build native executables
"\(project):build"
}
}.join("\n")
steps {
new Common.Checkout {}
new {
name = "gradle build java executables"
shell = "bash"
run = command
}
new Artifact.Upload {
name = "Upload executable artifacts"
with {
name = "executable-java"
path = "*/build/executable/**/*"
}
}
}

47
.github/jobs/BuildNativeJob.pkl vendored Normal file
View File

@@ -0,0 +1,47 @@
extends "GradleJob.pkl"
import "@gha/actions/Artifact.pkl"
/// Whether to link to musl. Otherwise, links to glibc.
musl: Boolean(implies(module.os == "linux")) = false
/// The Gradle project under which to generate the executable
project: String
extraGradleArgs {
when (os == "macOS" && arch == "amd64") {
"-Dpkl.targetArch=\(module.arch)"
}
when (musl) {
"-Dpkl.musl=true"
}
}
steps {
when (musl) {
new {
name = "Install musl and zlib"
run = read("../scripts/install_musl.sh").text
}
}
new {
name = "gradle buildNative"
shell = "bash"
run =
"""
./gradlew \(module.gradleArgs) \(project):buildNative
"""
}
new Artifact.Upload {
name = "Upload executable artifacts"
with {
name =
if (musl)
"executable-\(project)-alpine-\(module.os)-\(module.arch)"
else
"executable-\(project)-\(module.os)-\(module.arch)"
path = "\(project)/build/executable/**/*"
}
}
}

31
.github/jobs/DeployJob.pkl vendored Normal file
View File

@@ -0,0 +1,31 @@
extends "GradleJob.pkl"
import "@gha/actions/Artifact.pkl"
import "@gha/actions/Common.pkl"
import "@gha/Workflow.pkl"
import "@pkl.impl.ghactions/helpers.pkl"
local self = this
command: String
arch = "amd64"
os = "linux"
steps {
new Common.Checkout {}
new Artifact.Download {
with {
pattern = "executable-**"
}
}
new Workflow.Step {
run = "./gradlew \(self.gradleArgs) \(module.command)"
}
|> helpers.withMavenPublishSecrets
}
fixed job {
environment = "maven-release"
}

43
.github/jobs/GithubRelease.pkl vendored Normal file
View File

@@ -0,0 +1,43 @@
module GithubRelease
extends "PklJob.pkl"
import "@gha/actions/Artifact.pkl"
import "@gha/Context.pkl"
fixed job {
`runs-on` = "ubuntu-latest"
permissions {
contents = "write"
}
needs = "deploy-release"
steps {
new Artifact.Download {
with {
pattern = "executable-**"
}
}
new {
name = "Publish release on GitHub"
env {
["GH_TOKEN"] = Context.github.token
["TAG_NAME"] = Context.github.refName
["GIT_SHA"] = Context.github.sha
["GH_REPO"] = Context.github.repository
}
// language=bash
run =
#"""
# exclude build_artifacts.txt from publish
rm -f */build/executable/*.build_artifacts.txt
find */build/executable/* -type d | xargs rm -rf
gh release create ${TAG_NAME} \
--title "${TAG_NAME}" \
--target "${GIT_SHA}" \
--verify-tag \
--notes "Release notes: https://pkl-lang.org/main/current/release-notes/changelog.html#release-${TAG_NAME}" \
*/build/executable/*
"""#
}
}
}

93
.github/jobs/GradleJob.pkl vendored Normal file
View File

@@ -0,0 +1,93 @@
abstract module GradleJob
extends "PklJob.pkl"
import "@gha/actions/Common.pkl"
import "@gha/actions/Setup.pkl"
import "@gha/Workflow.pkl"
/// Whether this is a release build or not.
isRelease: Boolean = false
/// The architecture to use
arch: "amd64" | "aarch64" = "amd64"
/// The OS to run on.
os: "macOS" | "linux" | "windows" = "linux"
// TODO flip this to `true` when nightly macOS is available
/// Whether to run on nightly macOS.
nightlyMacOS: Boolean(implies(os == "macOS")) = false
extraGradleArgs: Listing<String>
steps: Listing<*Workflow.Step | Workflow.TypedStep>
/// The fetch depth to use when doing a git checkout.
fetchDepth: Int?
fixed gradleArgs =
new Listing {
"--info"
"--stacktrace"
"-DpklMultiJdkTesting=true"
when (isRelease) {
"-DreleaseBuild=true"
}
...extraGradleArgs
}.join(" ")
fixed job {
env {
["LANG"] = "en_US.UTF-8"
when (os == "windows") {
["JAVA_HOME"] = "/jdk"
}
}
when (os == "macOS") {
`if` =
let (cond = "github.repository_owner == 'apple'")
if (super.`if` != null)
"(\(super.`if`)) && \(cond)"
else
cond
}
`runs-on` =
if (os == "linux" && arch == "amd64")
"ubuntu-latest"
else if (os == "linux" && arch == "aarch64")
"ubuntu-24.04-arm"
else if (os == "windows")
"windows-latest"
else
new Listing {
"self-hosted"
"macos"
when (nightlyMacOS) {
"nightly"
}
}
steps {
// full checkout (needed for spotless)
new Common.Checkout {
when (fetchDepth != null) {
with {
`fetch-depth` = fetchDepth
}
}
}
new Setup.Java {
with {
`java-version` = "21"
distribution = "temurin"
cache = "gradle"
architecture =
if (arch == "amd64")
"x64"
else
"aarch64"
}
}
...module.steps
}
}

29
.github/jobs/PklJob.pkl vendored Normal file
View File

@@ -0,0 +1,29 @@
abstract module PklJob
import "@gha/Workflow.pkl"
/// Identify any jobs that must complete successfully before this job will run.
///
/// It can be a string or array of strings.
/// If a job fails or is skipped, all jobs that need it are skipped unless the jobs use a conditional expression that
/// causes the job to continue.
/// If a run contains a series of jobs that need each other, a failure or skip applies to all jobs in the dependency
/// chain from the point of failure or skip onwards. If you would like a job to run even if a job it is dependent on
/// did not succeed, use the `always()` conditional expression in `jobs.<job_id>.if`.
///
/// See: <https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idneeds>
needs: (String | *Listing<String>)?
/// A conditional to prevent a job from running unless a condition is met.
///
/// You can use any supported context and expression to create a conditional.
/// For more information on which contexts are supported in this key, see
/// [Contexts reference](https://docs.github.com/en/actions/reference/workflows-and-actions/contexts#context-availability).
@SourceCode { language = "GithubExpressionLanguage" }
`if`: String?
/// The underlying workflow job
fixed job: Workflow.Job = new {
`if` = module.`if`
needs = module.needs
}

18
.github/jobs/SimpleGradleJob.pkl vendored Normal file
View File

@@ -0,0 +1,18 @@
extends "GradleJob.pkl"
name: String = command
command: String
os = "linux"
steps {
new {
name = module.name
shell = "bash"
run =
"""
./gradlew \(module.gradleArgs) \(module.command)
"""
}
}