Skip to content

Commit da1fb52

Browse files
authored
Merge pull request #1 from ecrum19/dev
v2.0.0 - Compression and Optimization Refactoring
2 parents 5b4b8e9 + 5d1addd commit da1fb52

26 files changed

Lines changed: 4416 additions & 622 deletions

‎.github/workflows/publish-docker.yml‎

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ on:
99
workflow_dispatch:
1010
inputs:
1111
docker_tag:
12-
description: "Optional explicit Docker tag (example: v1.1.1)"
12+
description: "Optional explicit semantic Docker tag (example: 1.2.4 or v1.2.4)"
1313
required: false
1414
type: string
1515

16+
env:
17+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
18+
1619
jobs:
1720
docker:
1821
name: build-and-push-docker
@@ -71,8 +74,8 @@ jobs:
7174
ref_name = os.environ.get("GITHUB_REF_NAME", "")
7275
head_message = os.environ.get("HEAD_COMMIT_MESSAGE", "")
7376
manual_tag = os.environ.get("INPUT_DOCKER_TAG", "").strip()
74-
semver = re.compile(r"^v(\d+)\.(\d+)\.(\d+)$")
75-
explicit_from_commit = re.search(r"\[(?:publish-docker|docker)=([A-Za-z0-9_.-]+)\]", head_message)
77+
semver = re.compile(r"^v?(\d+)\.(\d+)\.(\d+)$")
78+
explicit_from_commit = re.search(r"\[(?:publish-docker|docker)=(v?\d+\.\d+\.\d+)\]", head_message)
7679
7780
def parse_max(tags):
7881
best = (-1, -1, -1)
@@ -105,16 +108,22 @@ jobs:
105108
best = max(best, parse_max(tags))
106109
major, minor, patch = best
107110
if major < 0:
108-
resolved_tag = "v1.0.0"
111+
resolved_tag = "1.0.0"
109112
else:
110-
resolved_tag = f"v{major}.{minor}.{patch + 1}"
113+
resolved_tag = f"{major}.{minor}.{patch + 1}"
111114
112-
if not re.match(r"^[A-Za-z0-9_.-]+$", resolved_tag):
113-
raise SystemExit(f"Invalid Docker tag: {resolved_tag}")
114-
print(f"Resolved Docker tag: {resolved_tag}")
115+
match = semver.fullmatch(resolved_tag)
116+
if not match:
117+
raise SystemExit(
118+
f"Docker release tag must match MAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH: {resolved_tag}"
119+
)
120+
version_tag = ".".join(match.groups())
121+
version_tag_with_v = f"v{version_tag}"
122+
print(f"Resolved Docker tags: {version_tag}, {version_tag_with_v}, latest")
115123
116124
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as f:
117-
f.write(f"next_version={resolved_tag}\n")
125+
f.write(f"version_tag={version_tag}\n")
126+
f.write(f"version_tag_with_v={version_tag_with_v}\n")
118127
PY
119128
120129
- name: Docker metadata
@@ -123,7 +132,8 @@ jobs:
123132
with:
124133
images: ecrum19/vcf-rdfizer
125134
tags: |
126-
type=raw,value=${{ steps.version.outputs.next_version }}
135+
type=raw,value=${{ steps.version.outputs.version_tag }}
136+
type=raw,value=${{ steps.version.outputs.version_tag_with_v }}
127137
type=raw,value=latest
128138
129139
- name: Build and push

‎.github/workflows/publish-python.yml‎

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,36 @@ name: publish-python
33
on:
44
push:
55
tags:
6-
- "v*"
6+
- "v*.*.*"
77
workflow_dispatch:
88
inputs:
99
release_tag:
10-
description: "Optional Git tag to sync from, for example v1.2.3"
11-
required: false
10+
description: "Existing Git tag to validate, for example v1.2.4. Manual runs never publish to PyPI."
11+
required: true
1212
type: string
1313

14+
env:
15+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
16+
1417
jobs:
1518
build:
1619
name: build-sdist-wheel
1720
runs-on: ubuntu-latest
21+
env:
22+
RELEASE_TAG: ${{ github.event.inputs.release_tag || github.ref_name }}
1823
steps:
1924
- name: Checkout
2025
uses: actions/checkout@v4
26+
with:
27+
ref: ${{ github.event.inputs.release_tag || github.ref }}
2128

2229
- name: Setup Python
2330
uses: actions/setup-python@v5
2431
with:
2532
python-version: "3.11"
2633

27-
- name: Sync release metadata from tag
28-
env:
29-
RELEASE_TAG: ${{ github.event.inputs.release_tag || github.ref_name }}
30-
run: |
31-
python scripts/release.py --tag "${RELEASE_TAG}" --workflow
34+
- name: Validate committed release metadata
35+
run: python scripts/release.py --check-tag "${RELEASE_TAG}"
3236

3337
- name: Build package
3438
run: |
@@ -38,8 +42,6 @@ jobs:
3842
python -m twine check dist/*
3943
4044
- name: Verify built artifact versions
41-
env:
42-
RELEASE_TAG: ${{ github.event.inputs.release_tag || github.ref_name }}
4345
run: |
4446
python - <<'PY'
4547
from pathlib import Path
@@ -85,6 +87,27 @@ jobs:
8587
print(f" {name}")
8688
PY
8789
90+
- name: Smoke-test installed wheel
91+
run: |
92+
python -m venv /tmp/vcf-rdfizer-wheel-test
93+
/tmp/vcf-rdfizer-wheel-test/bin/python -m pip install --no-deps dist/*.whl
94+
(
95+
cd /tmp
96+
/tmp/vcf-rdfizer-wheel-test/bin/vcf-rdfizer --help
97+
/tmp/vcf-rdfizer-wheel-test/bin/python - <<'PY'
98+
import importlib.resources
99+
from pathlib import Path
100+
101+
import vcf_rdfizer
102+
103+
rules = importlib.resources.files("vcf_rdfizer_data").joinpath("rules/default_rules.ttl")
104+
if not rules.is_file():
105+
raise SystemExit("Packaged default rules are missing")
106+
if not vcf_rdfizer.resolve_default_rules_path(Path(vcf_rdfizer.__file__).resolve().parent).is_file():
107+
raise SystemExit("Installed wrapper cannot resolve packaged default rules")
108+
PY
109+
)
110+
88111
- name: Upload artifacts
89112
uses: actions/upload-artifact@v4
90113
with:

‎.github/workflows/tests.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
- "**"
77
pull_request:
88

9+
env:
10+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
11+
912
jobs:
1013
wrapper-cross-platform:
1114
name: wrapper-unit (${{ matrix.os }})

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ test/test_vcf_files/*
88
!test/test_vcf_files/test-100.vcf
99
!test/test_vcf_files/test-1k.vcf
1010
!test/test_vcf_files/test-10k.vcf
11+
!test/test_vcf_files/test-larger.vcf.gz
12+
1113
RMLStreamer-v2.5.0-standalone.jar
1214
out/
1315
tsv/

‎Dockerfile‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
ARG RMLSTREAMER_VERSION=2.5.0
2+
ARG HDT_JAVA_PACKAGE_VERSION=3.0.10
23

34
FROM eclipse-temurin:11-jre AS build-hdt-cpp
45

@@ -37,6 +38,7 @@ RUN mkdir -p /opt/third_party_licenses \
3738
FROM eclipse-temurin:11-jre
3839

3940
ARG RMLSTREAMER_VERSION
41+
ARG HDT_JAVA_PACKAGE_VERSION
4042

4143
RUN apt-get update \
4244
&& apt-get install -y --no-install-recommends \
@@ -50,30 +52,50 @@ RUN apt-get update \
5052
gzip \
5153
libserd-0-0 \
5254
nodejs \
55+
python3 \
56+
python3-venv \
5357
time \
5458
&& rm -rf /var/lib/apt/lists/*
5559

60+
RUN python3 -m venv /opt/pycottas-venv \
61+
&& /opt/pycottas-venv/bin/pip install --no-cache-dir pycottas
62+
5663
RUN mkdir -p /opt/rmlstreamer \
5764
&& curl -fsSL \
5865
-o /opt/rmlstreamer/RMLStreamer-v${RMLSTREAMER_VERSION}-standalone.jar \
5966
https://github.com/RMLio/RMLStreamer/releases/download/v${RMLSTREAMER_VERSION}/RMLStreamer-v${RMLSTREAMER_VERSION}-standalone.jar
6067

68+
RUN mkdir -p /opt/hdt-java \
69+
&& curl -fsSL \
70+
-o /tmp/hdt-java-package.tar.gz \
71+
https://repo1.maven.org/maven2/org/rdfhdt/hdt-java-package/${HDT_JAVA_PACKAGE_VERSION}/hdt-java-package-${HDT_JAVA_PACKAGE_VERSION}-distribution.tar.gz \
72+
&& tar -xzf /tmp/hdt-java-package.tar.gz -C /opt/hdt-java --strip-components=1 \
73+
&& rm -f /tmp/hdt-java-package.tar.gz
74+
6175
COPY --from=build-hdt-cpp /usr/local/bin/rdf2hdt /usr/local/bin/rdf2hdt
6276
COPY --from=build-hdt-cpp /usr/local/bin/hdt2rdf /usr/local/bin/hdt2rdf
6377
COPY --from=build-hdt-cpp /usr/local/lib/libcds* /usr/local/lib/
6478
COPY --from=build-hdt-cpp /usr/local/lib/libhdt* /usr/local/lib/
6579
COPY --from=build-hdt-cpp /opt/third_party_licenses/ /usr/share/licenses/vcf-rdfizer/
6680
COPY THIRD_PARTY_NOTICES.md /usr/share/licenses/vcf-rdfizer/THIRD_PARTY_NOTICES.md
6781
COPY src/*.sh /opt/vcf-rdfizer/
82+
COPY src/*.py /opt/vcf-rdfizer/
6883

6984
RUN chmod +x /opt/vcf-rdfizer/*.sh \
85+
&& find /opt/hdt-java/bin -type f -exec chmod +x {} \; \
7086
&& chmod +x /usr/local/bin/rdf2hdt \
7187
&& chmod +x /usr/local/bin/hdt2rdf
7288

7389
ENV RMLSTREAMER_JAR=/opt/rmlstreamer/RMLStreamer-v${RMLSTREAMER_VERSION}-standalone.jar
7490
ENV JAR=/opt/rmlstreamer/RMLStreamer-v${RMLSTREAMER_VERSION}-standalone.jar
91+
ENV HDT_JAVA_HOME=/opt/hdt-java
7592
ENV RDF2HDT_BIN=/usr/local/bin/rdf2hdt
7693
ENV HDT2RDF_BIN=/usr/local/bin/hdt2rdf
94+
ENV COTTAS_PYTHON_BIN=/opt/pycottas-venv/bin/python
7795
ENV LD_LIBRARY_PATH=/usr/local/lib
7896

97+
# COTTAS creates a temporary DuckDB database in the container working
98+
# directory. The wrapper runs containers as the host UID/GID, so this path
99+
# must be writable without requiring root or creating root-owned host files.
100+
RUN mkdir -p /work && chmod 1777 /work
79101
WORKDIR /work

0 commit comments

Comments
 (0)