diff --git a/.github/workflows/slack-alert.yml b/.github/workflows/slack-alert.yml
new file mode 100644
index 0000000..8f65cf5
--- /dev/null
+++ b/.github/workflows/slack-alert.yml
@@ -0,0 +1,22 @@
+name: slack-alert
+
+on:
+ workflow_run:
+ workflows: [tests]
+ types: [completed]
+
+jobs:
+ on-failure:
+ runs-on: ubuntu-latest
+ if: ${{ github.event.workflow_run.conclusion == 'failure' }}
+ steps:
+ - name: Send Slack Alert
+ id: slack
+ uses: slackapi/slack-github-action@v1.26.0
+ with:
+ payload: |
+ Github Actions ${{ github.event.workflow_run.conclusion }}
+ Repo: ${{github.event.workflow_run.repository.name }}
+ Workflow URL: ${{ github.event.workflow_run.html_url }}
+ env:
+ SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d36f68d..f77a083 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -5,6 +5,9 @@ on:
branches: [master, stable-*]
pull_request:
branches: [master, stable-*]
+ schedule:
+ # Every Sunday, rerun
+ - cron: "0 12 * * 0"
jobs:
tests:
@@ -56,7 +59,7 @@ jobs:
if-no-files-found: error
tests-new-dockcross:
- name: Dockcross ${{ matrix.dockcross-tag }} Java ${{ matrix.java-version }} ${{ matrix.os }}
+ name: Dockcross ${{ matrix.dockcross-tag }} Java ${{ matrix.java-version }} ${{ matrix.os }} ${{ matrix.dockcross-only }}
runs-on: ${{ matrix.os }}
strategy:
@@ -64,7 +67,8 @@ jobs:
os: [ubuntu-latest]
java-distribution: [adopt]
java-version: [17]
- dockcross-tag: ["20220906-e88a3ce", "20230116-670f7f7"]
+ dockcross-tag: ["20230116-670f7f7", "20240418-88c04a4", "latest"]
+ dockcross-only: ["android-arm", "android-arm64", "linux-arm64", "linux-armv5", "linux-armv7", "linux-s390x", "linux-ppc64le", "linux-x64", "linux-x86", "windows-static-x64", "windows-static-x86"]
steps:
- uses: actions/checkout@v2.1.1
@@ -85,7 +89,7 @@ jobs:
${{ runner.os }}-maven-
- name: Tests
- run: mvn "-Dh3.system.prune=true" "-Dh3.dockcross.tag=${{ matrix.dockcross-tag }}" -B -V clean test
+ run: mvn "-Dh3.system.prune=true" "-Dh3.dockcross.tag=${{ matrix.dockcross-tag }}" "-Dh3.dockcross.only=${{ matrix.dockcross-only }}" -B -V clean test
tests-no-docker:
name: Java (No Docker) ${{ matrix.java-version }} ${{ matrix.os }}
@@ -94,7 +98,8 @@ jobs:
strategy:
matrix:
# TODO: Docker on macos-latest running is not working
- os: [macos-latest, windows-latest]
+ # TODO: Windows pinned back
+ os: [macos-latest, windows-2019]
java-distribution: [adopt]
java-version: [8, 11, 15, 17]
diff --git a/pom.xml b/pom.xml
index 1d6e3e8..9ebd6a2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -72,6 +72,7 @@
true
false
20210624-de7b1b0
+
false
@@ -270,6 +271,7 @@
${h3.use.docker}
${h3.system.prune}
${h3.dockcross.tag}
+ ${h3.dockcross.only}
${h3.github.artifacts.use}
${h3.github.artifacts.by_run}
diff --git a/src/main/c/h3-java/build-h3.sh b/src/main/c/h3-java/build-h3.sh
index 741a023..883b60d 100755
--- a/src/main/c/h3-java/build-h3.sh
+++ b/src/main/c/h3-java/build-h3.sh
@@ -25,6 +25,7 @@
# system prune will be run after each step
# (i.e. for disk space constrained environments like CI)
# dockcross-tag - Tag name for dockcross
+# dockcross-only - When set, build only a specific architecture with dockcross.
# github-artifacts - When set, all build artifacts are retrieved from Github
# Actions artifacts rather than built locally (overrides
# all other settings.)
@@ -44,8 +45,9 @@ GIT_REVISION=$2
USE_DOCKER=$3
SYSTEM_PRUNE=$4
DOCKCROSS_TAG=$5
-GITHUB_ARTIFACTS=$6
-GITHUB_ARTIFACTS_RUN=$7
+DOCKCROSS_ONLY=$6
+GITHUB_ARTIFACTS=$7
+GITHUB_ARTIFACTS_RUN=$8
if $GITHUB_ARTIFACTS; then
src/main/c/h3-java/pull-from-github.sh "$GITHUB_ARTIFACTS_RUN"
@@ -180,10 +182,15 @@ UPGRADE_CMAKE=true
CMAKE_ROOT=target/cmake-3.23.2-linux-x86_64
mkdir -p $CMAKE_ROOT
+DOCKCROSS_IMAGES="android-arm android-arm64 linux-arm64 linux-armv5 linux-armv7 linux-s390x linux-ppc64le linux-x64 linux-x86 windows-static-x64 windows-static-x86"
+if ! $DOCKCROSS_ONLY; then
+ DOCKCROSS_IMAGES=$DOCKCROSS_ONLY
+ echo Building only: $DOCKCROSS_IMAGES
+fi
+
# linux-armv6 excluded because of build failure
# linux-mips excluded due to manifest error
-for image in android-arm android-arm64 linux-arm64 linux-armv5 linux-armv7 linux-s390x \
- linux-ppc64le linux-x64 linux-x86 windows-static-x64 windows-static-x86; do
+for image in $DOCKCROSS_IMAGES; do
# Setup for using dockcross
BUILD_ROOT=target/h3-java-build-$image
@@ -210,6 +217,9 @@ for image in android-arm android-arm64 linux-arm64 linux-armv5 linux-armv7 linux
if [ -e $BUILD_ROOT/lib/libh3-java.dll ]; then cp $BUILD_ROOT/lib/libh3-java.dll $OUTPUT_ROOT ; fi
if $SYSTEM_PRUNE; then
+ # Remove the image we just ran
+ docker rmi dockcross/$image:$DOCKCROSS_TAG
+ # Aggressively try to free more disk space
docker system prune --force --all
docker system df
rm $BUILD_ROOT/dockcross
diff --git a/src/main/java/com/uber/h3core/H3CoreLoader.java b/src/main/java/com/uber/h3core/H3CoreLoader.java
index e40df91..9533e64 100644
--- a/src/main/java/com/uber/h3core/H3CoreLoader.java
+++ b/src/main/java/com/uber/h3core/H3CoreLoader.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2018 Uber Technologies, Inc.
+ * Copyright 2017-2018, 2024 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,12 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
import java.util.Locale;
+import java.util.Set;
/** Extracts the native H3 core library to the local filesystem and loads it. */
public final class H3CoreLoader {
@@ -60,11 +65,6 @@ private static void copyStream(InputStream in, OutputStream out) throws IOExcept
* @throws UnsatisfiedLinkError The resource path does not exist
*/
static void copyResource(String resourcePath, File newH3LibFile) throws IOException {
- // Set the permissions
- newH3LibFile.setReadable(true);
- newH3LibFile.setWritable(true, true);
- newH3LibFile.setExecutable(true, true);
-
// Shove the resource into the file and close it
try (InputStream resource = H3CoreLoader.class.getResourceAsStream(resourcePath)) {
if (resource == null) {
@@ -93,6 +93,24 @@ public static NativeMethods loadNatives() throws IOException {
return loadNatives(os, arch);
}
+ private static File createTempLibraryFile(OperatingSystem os) throws IOException {
+ if (os.isPosix()) {
+ // Note this is already done by the implementation of Files.createTempFile that I looked at,
+ // but the javadoc does not seem to gaurantee the permissions will be restricted to owner
+ // write.
+ final FileAttribute> attr =
+ PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"));
+ return Files.createTempFile("libh3-java", os.getSuffix(), attr).toFile();
+ } else {
+ // When not a POSIX OS, try to ensure the permissions are secure
+ final File f = Files.createTempFile("libh3-java", os.getSuffix()).toFile();
+ f.setReadable(true, true);
+ f.setWritable(true, true);
+ f.setExecutable(true, true);
+ return f;
+ }
+ }
+
/**
* For use when the H3 library should be unpacked from the JAR and loaded. The native library for
* the specified operating system and architecture will be extract.
@@ -115,8 +133,7 @@ public static synchronized NativeMethods loadNatives(OperatingSystem os, String
final String dirName = String.format("%s-%s", os.getDirName(), arch);
final String libName = String.format("libh3-java%s", os.getSuffix());
- final File newLibraryFile = File.createTempFile("libh3-java", os.getSuffix());
-
+ final File newLibraryFile = createTempLibraryFile(os);
newLibraryFile.deleteOnExit();
copyResource(String.format("/%s/%s", dirName, libName), newLibraryFile);
@@ -146,13 +163,20 @@ public enum OperatingSystem {
ANDROID(".so"),
DARWIN(".dylib"),
FREEBSD(".so"),
- WINDOWS(".dll"),
+ WINDOWS(".dll", false),
LINUX(".so");
private final String suffix;
+ private final boolean posix;
OperatingSystem(String suffix) {
this.suffix = suffix;
+ this.posix = true;
+ }
+
+ OperatingSystem(String suffix, boolean posix) {
+ this.suffix = suffix;
+ this.posix = posix;
}
/** Suffix for native libraries. */
@@ -164,6 +188,11 @@ public String getSuffix() {
public String getDirName() {
return name().toLowerCase(H3_CORE_LOCALE);
}
+
+ /** Whether to try to use POSIX file permissions when creating the native library temp file. */
+ public boolean isPosix() {
+ return this.posix;
+ }
}
/**
diff --git a/src/test/java/com/uber/h3core/TestH3CoreLoader.java b/src/test/java/com/uber/h3core/TestH3CoreLoader.java
index cd0b8ea..f822b19 100644
--- a/src/test/java/com/uber/h3core/TestH3CoreLoader.java
+++ b/src/test/java/com/uber/h3core/TestH3CoreLoader.java
@@ -19,6 +19,7 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
import org.junit.Test;
/** H3CoreLoader is mostly tested by {@link TestH3CoreFactory}. This also tests OS detection. */
@@ -60,7 +61,7 @@ public void testDetectArch() {
@Test(expected = UnsatisfiedLinkError.class)
public void testExtractNonexistant() throws IOException {
- File tempFile = File.createTempFile("test-extract-resource", null);
+ File tempFile = Files.createTempFile("test-extract-resource", null).toFile();
tempFile.deleteOnExit();