-
Notifications
You must be signed in to change notification settings - Fork 0
Add packaging mechanism to automatically build SV-Comp zip
#30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
550d304
d2c6708
8aa954f
2b6fd70
c420233
1d742b1
5057d82
e634499
cdf7c4a
0e6cad5
54dd68d
d3136eb
e4965d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,11 @@ name: Java CI with Gradle | |
| on: | ||
| push: | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| env: | ||
| SVCOMP_REFERENCE_URL: https://zenodo.org/api/records/17748741/files/swat-verify.zip/content | ||
| SVCOMP_REFERENCE_MD5: 8c776d19ac33ecf5c1c7441d16cc18a6 | ||
|
|
||
| jobs: | ||
| build: | ||
|
|
@@ -18,8 +23,142 @@ jobs: | |
| distribution: 'temurin' | ||
| - name: Setup Gradle | ||
| uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While you are at it, could you also check why the setup-gradle v4 is referenced using this hash I assume? is that the proper way to do that? (I know this is older then your changes but I was wondering for some time) |
||
| - name: Prepare Solver Dependencies | ||
| run: ./gradlew copyNativeLibs | ||
| - name: Build | ||
| run: ./gradlew build -x test | ||
| run: ./gradlew --no-daemon build -x test | ||
| - name: Build WitnessCreator JAR | ||
| run: ./gradlew --no-daemon :targets:sv-comp:WitnessCreator:shadowJar | ||
|
Comment on lines
+30
to
+31
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed could you also move the full witness creator into its own repo that publishes an artifact we can use here? |
||
| - name: Upload JARs | ||
| if: github.event_name != 'pull_request' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: release-jars-${{ github.sha }} | ||
| path: | | ||
| symbolic-executor/lib/symbolic-executor.jar | ||
| targets/sv-comp/WitnessCreator/build/libs/WitnessCreator.jar | ||
| if-no-files-found: error | ||
| retention-days: 1 | ||
|
|
||
| package: | ||
| needs: build | ||
| if: >- | ||
| github.event_name == 'workflow_dispatch' || | ||
| (github.event_name == 'push' && ( | ||
| github.ref == 'refs/heads/main' || | ||
| github.ref == 'refs/heads/dev' || | ||
| startsWith(github.ref, 'refs/tags/') | ||
| )) | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| steps: | ||
| - uses: actions/checkout@v5 | ||
| - name: Download JARs | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: release-jars-${{ github.sha }} | ||
| path: ${{ runner.temp }}/release-jars | ||
| - name: Determine release channel | ||
| id: meta | ||
| run: | | ||
| ref_type="${GITHUB_REF_TYPE}" | ||
| ref_name="${GITHUB_REF_NAME}" | ||
| sha_short="${GITHUB_SHA::7}" | ||
|
|
||
| channel="" # release/tag name; empty -> build artifact only, no release | ||
| release="false" | ||
| rolling="false" # rolling channels move their tag to the current commit | ||
| prerelease="false" | ||
|
|
||
| if [[ "$ref_type" == "tag" ]]; then | ||
| channel="$ref_name" | ||
| release="true" | ||
| elif [[ "$ref_name" == "main" ]]; then | ||
| channel="latest" | ||
| release="true" | ||
| rolling="true" | ||
| elif [[ "$ref_name" == "dev" ]]; then | ||
| channel="latest-dev" | ||
| release="true" | ||
| rolling="true" | ||
| prerelease="true" | ||
| fi | ||
|
|
||
| # Channel-stable asset name gives the nightly cron a fixed download URL; | ||
| # the exact commit is recorded in the release notes and BUILD_INFO.txt. | ||
| if [[ -n "$channel" ]]; then | ||
| version="$channel" | ||
| else | ||
| version="$sha_short" | ||
| fi | ||
| zip_name="swat-svcomp-${version}.zip" | ||
|
|
||
| { | ||
| echo "channel=${channel}" | ||
| echo "version=${version}" | ||
| echo "zip-name=${zip_name}" | ||
| echo "release=${release}" | ||
| echo "rolling=${rolling}" | ||
| echo "prerelease=${prerelease}" | ||
| } >> "${GITHUB_OUTPUT}" | ||
| - name: Download SV-COMP reference runtime | ||
| run: | | ||
| curl --fail --location --retry 3 --output "${RUNNER_TEMP}/swat-verify.zip" "${SVCOMP_REFERENCE_URL}" | ||
| echo "${SVCOMP_REFERENCE_MD5} ${RUNNER_TEMP}/swat-verify.zip" | md5sum --check - | ||
| unzip -q "${RUNNER_TEMP}/swat-verify.zip" -d "${RUNNER_TEMP}/swat-reference" | ||
| - name: Pack SV-COMP ZIP | ||
| env: | ||
| SWAT_SVCOMP_VERSION: ${{ steps.meta.outputs.version }} | ||
| SWAT_SVCOMP_ARTIFACT_DIR: ${{ runner.temp }}/release-jars | ||
| SWAT_SVCOMP_REFERENCE_DIR: ${{ runner.temp }}/swat-reference/swat-verify | ||
| SWAT_SVCOMP_COMMIT: ${{ github.sha }} | ||
| SWAT_SVCOMP_REF: ${{ github.ref_name }} | ||
| SWAT_SVCOMP_CHANNEL: ${{ steps.meta.outputs.channel }} | ||
| run: scripts/package-svcomp.sh | ||
| - name: Upload SV-COMP ZIP artifact | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: swat-svcomp-${{ steps.meta.outputs.version }} | ||
| path: build/distributions/${{ steps.meta.outputs.zip-name }} | ||
| if-no-files-found: error | ||
| - name: Publish release | ||
| if: steps.meta.outputs.release == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| CHANNEL: ${{ steps.meta.outputs.channel }} | ||
| ZIP_NAME: ${{ steps.meta.outputs.zip-name }} | ||
| ROLLING: ${{ steps.meta.outputs.rolling }} | ||
| PRERELEASE: ${{ steps.meta.outputs.prerelease }} | ||
| run: | | ||
| zip_path="build/distributions/${ZIP_NAME}" | ||
| notes="$(printf 'Automated SWAT SV-COMP package.\n\nRef: %s\nCommit: %s\nRun: %s/%s/actions/runs/%s\n' \ | ||
| "$GITHUB_REF_NAME" "$GITHUB_SHA" "$GITHUB_SERVER_URL" "$GITHUB_REPOSITORY" "$GITHUB_RUN_ID")" | ||
|
|
||
| prerelease_flag=() | ||
| [[ "$PRERELEASE" == "true" ]] && prerelease_flag=(--prerelease) | ||
|
|
||
| if [[ "$ROLLING" == "true" ]]; then | ||
| # Refresh the rolling channel: drop the old release + tag, then recreate | ||
| # it at the current commit so the tag always tracks the channel head. | ||
| # Uses the default GITHUB_TOKEN, so the new tag does not retrigger CI. | ||
| gh release delete "$CHANNEL" --yes --cleanup-tag 2>/dev/null || true | ||
| gh release create "$CHANNEL" "$zip_path" \ | ||
| --target "$GITHUB_SHA" \ | ||
| --title "SWAT ${CHANNEL} (${GITHUB_SHA::7})" \ | ||
| --notes "$notes" \ | ||
| "${prerelease_flag[@]}" | ||
| else | ||
| # Permanent, version-tagged release (the tag already points at this commit). | ||
| if gh release view "$CHANNEL" >/dev/null 2>&1; then | ||
| gh release upload "$CHANNEL" "$zip_path" --clobber | ||
| else | ||
| gh release create "$CHANNEL" "$zip_path" \ | ||
| --title "SWAT ${CHANNEL}" \ | ||
| --notes "$notes" \ | ||
| "${prerelease_flag[@]}" | ||
| fi | ||
| fi | ||
|
|
||
| test: | ||
| needs: build | ||
|
|
@@ -82,4 +221,4 @@ jobs: | |
| java-version: '17' | ||
| distribution: 'temurin' | ||
| - name: Generate and submit dependency graph | ||
| uses: gradle/actions/dependency-submission@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4 | ||
| uses: gradle/actions/dependency-submission@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,180 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| # This script packages artifacts that were already produced by CI. It must not | ||
| # invoke Gradle, create virtual environments, or download dependencies. | ||
| # | ||
| # Generated files are expected in the repository checkout after the CI build. | ||
| # Set SWAT_SVCOMP_ARTIFACT_DIR only if those generated files live somewhere | ||
| # else. The artifact root must contain: | ||
| # | ||
| # - symbolic-executor/lib/symbolic-executor.jar | ||
| # - targets/sv-comp/WitnessCreator/build/libs/WitnessCreator.jar | ||
| # | ||
| # Set SWAT_SVCOMP_REFERENCE_DIR to the extracted Zenodo reference package root | ||
| # from https://zenodo.org/records/17748741. The reference root is used for the | ||
| # pinned SV-COMP Python environment and JavaSMT compatibility JAR: | ||
| # | ||
| # - .venv_ubuntu_24_04_1__x86_64/ | ||
| # | ||
| # Z3 is taken from the vendored Linux distribution ZIP in this repository. | ||
| # | ||
| ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" | ||
| cd "$ROOT_DIR" | ||
|
|
||
| VERSION="${SWAT_SVCOMP_VERSION:-$(git rev-parse --short HEAD)}" | ||
| COMMIT="${SWAT_SVCOMP_COMMIT:-$(git rev-parse HEAD 2>/dev/null || echo unknown)}" | ||
| REF="${SWAT_SVCOMP_REF:-$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)}" | ||
| CHANNEL="${SWAT_SVCOMP_CHANNEL:-}" | ||
| PACKAGE_NAME="swat-svcomp-${VERSION}" | ||
| WORK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/swat-svcomp-package.XXXXXX")" | ||
| PACKAGE_DIR="${WORK_DIR}/${PACKAGE_NAME}" | ||
| DIST_DIR="${ROOT_DIR}/build/distributions" | ||
| SUPPORT_DIR="${ROOT_DIR}/scripts/svcomp-package" | ||
| ARTIFACT_DIR="$(cd "${SWAT_SVCOMP_ARTIFACT_DIR:-$ROOT_DIR}" && pwd)" | ||
| REFERENCE_DIR="${SWAT_SVCOMP_REFERENCE_DIR:-}" | ||
| VENV_DIR_NAME="${SWAT_SVCOMP_VENV_DIR_NAME:-.venv_ubuntu_24_04_1__x86_64}" | ||
| LINUX_Z3_DIST="z3-4.15.4-x64-glibc-2.39" | ||
| LINUX_Z3_ZIP="${ROOT_DIR}/libs/${LINUX_Z3_DIST}.zip" | ||
|
|
||
| if [[ -n "$REFERENCE_DIR" ]]; then | ||
| REFERENCE_DIR="$(cd "$REFERENCE_DIR" && pwd)" | ||
| fi | ||
|
|
||
| fail() { | ||
| echo "error: $*" >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| artifact_file() { | ||
| local rel="$1" | ||
| local path="${ARTIFACT_DIR}/${rel}" | ||
| [[ -f "$path" ]] || fail "missing built artifact file: ${path}" | ||
| printf '%s\n' "$path" | ||
| } | ||
|
|
||
| reference_file() { | ||
| local rel="$1" | ||
| [[ -n "$REFERENCE_DIR" ]] || fail "SWAT_SVCOMP_REFERENCE_DIR is required for ${rel}" | ||
|
|
||
| local path="${REFERENCE_DIR}/${rel}" | ||
| [[ -f "$path" ]] || fail "missing Zenodo reference file: ${path}" | ||
| printf '%s\n' "$path" | ||
| } | ||
|
|
||
| first_artifact_file() { | ||
| local path | ||
| for rel in "$@"; do | ||
| path="${ARTIFACT_DIR}/${rel}" | ||
| if [[ -f "$path" ]]; then | ||
| printf '%s\n' "$path" | ||
| return 0 | ||
| fi | ||
| done | ||
| fail "missing built artifact file; checked: $*" | ||
| } | ||
|
|
||
| copy_tree_files() { | ||
| local src="$1" | ||
| local dest="$2" | ||
| mkdir -p "$dest" | ||
| find "$src" -type f \ | ||
| ! -path '*/__pycache__/*' \ | ||
| ! -path '*/.venv/*' \ | ||
| ! -name '*.pyc' \ | ||
| ! -name '*.pyo' \ | ||
| ! -name '*.iml' \ | ||
| -print0 | while IFS= read -r -d '' file; do | ||
| local rel="${file#"$src"/}" | ||
| mkdir -p "$dest/$(dirname "$rel")" | ||
| cp "$file" "$dest/$rel" | ||
| done | ||
| } | ||
|
|
||
| copy_artifact_file() { | ||
| local src="$1" | ||
| local dest="$2" | ||
| local mode="${3:-0644}" | ||
| mkdir -p "$(dirname "$dest")" | ||
| install -m "$mode" "$src" "$dest" | ||
| } | ||
|
|
||
| copy_artifact_tree() { | ||
| local src="$1" | ||
| local dest="$2" | ||
| [[ -d "$src" ]] || fail "missing artifact directory: ${src}" | ||
| mkdir -p "$(dirname "$dest")" | ||
| cp -a "$src" "$dest" | ||
| } | ||
|
|
||
| install_z3_runtime_file() { | ||
| local name="$1" | ||
| local mode="${2:-0644}" | ||
| local dest="${PACKAGE_DIR}/libs/java-library-path/${name}" | ||
|
|
||
| [[ -f "$LINUX_Z3_ZIP" ]] || fail "missing vendored Linux Z3 distribution: ${LINUX_Z3_ZIP}" | ||
| mkdir -p "$(dirname "$dest")" | ||
| unzip -p "$LINUX_Z3_ZIP" "${LINUX_Z3_DIST}/bin/${name}" > "$dest" | ||
| chmod "$mode" "$dest" | ||
| } | ||
|
|
||
| echo "Packaging repository files from: ${ROOT_DIR}" | ||
| echo "Packaging built artifacts from: ${ARTIFACT_DIR}" | ||
|
|
||
| echo "Creating package staging directory: ${PACKAGE_DIR}" | ||
| mkdir -p "$PACKAGE_DIR" | ||
| { | ||
| echo "version=${VERSION}" | ||
| echo "channel=${CHANNEL}" | ||
| echo "ref=${REF}" | ||
| echo "commit=${COMMIT}" | ||
| } > "$PACKAGE_DIR/BUILD_INFO.txt" | ||
|
|
||
| install -m 0644 LICENSE "$PACKAGE_DIR/LICENSE" | ||
| install -m 0644 Third-Party-Licenses.html "$PACKAGE_DIR/Third-Party-Licenses.html" | ||
| install -m 0644 "$SUPPORT_DIR/README.md" "$PACKAGE_DIR/README.md" | ||
| install -m 0755 "$SUPPORT_DIR/run-swat.sh" "$PACKAGE_DIR/run-swat.sh" | ||
| install -m 0755 "$SUPPORT_DIR/compile-target.sh" "$PACKAGE_DIR/compile-target.sh" | ||
| install -m 0755 "$SUPPORT_DIR/smoketest.sh" "$PACKAGE_DIR/smoketest.sh" | ||
| install -m 0755 "$SUPPORT_DIR/run_swat.py" "$PACKAGE_DIR/run_swat.py" | ||
| install -m 0644 targets/sv-comp/sv-comp.cfg "$PACKAGE_DIR/sv-comp.cfg" | ||
|
|
||
| EXECUTOR_JAR="$(first_artifact_file \ | ||
| symbolic-executor/lib/symbolic-executor.jar \ | ||
| symbolic-executor/build/libs/symbolic-executor-all.jar)" | ||
| copy_artifact_file "$EXECUTOR_JAR" "$PACKAGE_DIR/symbolic-executor/lib/symbolic-executor.jar" | ||
|
|
||
| copy_tree_files symbolic-explorer "$PACKAGE_DIR/symbolic-explorer" | ||
|
|
||
| WITNESS_CREATOR_JAR="$(artifact_file targets/sv-comp/WitnessCreator/build/libs/WitnessCreator.jar)" | ||
| copy_artifact_file "$WITNESS_CREATOR_JAR" "$PACKAGE_DIR/WitnessCreator/build/libs/WitnessCreator.jar" | ||
| mkdir -p "$PACKAGE_DIR/WitnessCreator/witnesses" | ||
| install -m 0644 targets/sv-comp/WitnessCreator/witnesses/default_violation.st "$PACKAGE_DIR/WitnessCreator/witnesses/default_violation.st" | ||
| install -m 0644 targets/sv-comp/WitnessCreator/witnesses/witness.st "$PACKAGE_DIR/WitnessCreator/witnesses/witness.st" | ||
|
|
||
| install_z3_runtime_file z3 0755 | ||
| install_z3_runtime_file libz3.so | ||
| install_z3_runtime_file libz3java.so | ||
| install_z3_runtime_file com.microsoft.z3.jar | ||
| install_z3_runtime_file libz3.a | ||
| JAVA_SMT_JAR="$(reference_file libs/java-library-path/java-smt-latest.jar)" | ||
| copy_artifact_file "$JAVA_SMT_JAR" "$PACKAGE_DIR/libs/java-library-path/java-smt-latest.jar" | ||
|
|
||
| copy_tree_files "$SUPPORT_DIR/smoketest" "$PACKAGE_DIR/smoketest" | ||
|
|
||
| [[ -n "$REFERENCE_DIR" ]] || fail "SWAT_SVCOMP_REFERENCE_DIR must point to the extracted Zenodo package root for ${VENV_DIR_NAME}" | ||
| copy_artifact_tree "${REFERENCE_DIR}/${VENV_DIR_NAME}" "${PACKAGE_DIR}/${VENV_DIR_NAME}" | ||
|
|
||
| mkdir -p "$DIST_DIR" | ||
| ZIP_PATH="${DIST_DIR}/${PACKAGE_NAME}.zip" | ||
| ZIP_TMP="${WORK_DIR}/${PACKAGE_NAME}.zip" | ||
|
|
||
| echo "Creating ZIP: ${ZIP_PATH}" | ||
| ( | ||
| cd "$WORK_DIR" | ||
| zip -qr "$ZIP_TMP" "$PACKAGE_NAME" | ||
| ) | ||
| cp "$ZIP_TMP" "$ZIP_PATH" | ||
|
|
||
| echo "Package created at: ${ZIP_PATH}" | ||
| echo "Staging directory left at: ${PACKAGE_DIR}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # SWAT SV-COMP Package | ||
|
|
||
| This archive contains a runnable SWAT package for SV-COMP style Java verification tasks. | ||
|
|
||
| Important entry points: | ||
|
|
||
| - `run-swat.sh`: verifier entry point used by BenchExec. | ||
| - `compile-target.sh`: helper used by `run_swat.py` to compile Java benchmark sources. | ||
| - `smoketest.sh`: runs SWAT on two bundled smoke-test targets. | ||
| - `sv-comp.cfg`: SWAT configuration for SV-COMP mode. | ||
|
|
||
| The package expects Java 17 and the bundled `.venv_ubuntu_24_04_1__x86_64` | ||
| Python environment. `run-swat.sh` intentionally uses only that environment. | ||
|
|
||
| Example: | ||
|
|
||
| ```sh | ||
| ./run-swat.sh ../../sv-benchmarks/java/properties/valid-assert.prp smoketest/common smoketest | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@k0lja Can you propose a different mechanism, perhaps another repository here that publishes the required files, I dont want to reference zenodo here in the CI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition, the venv we are using is built on the specific ubuntu version required by sv-comp. updating the dependencies is a hassle atm. Can you check if it could be possible either here or in the supporting repo (for the above) you can actually build the venv based on the requirements (
pip freezethe current venv) as part of the ci there? this would make updating the venv much easier