Unverified Commit 55a101e7 authored by Maxime Lefrançois's avatar Maxime Lefrançois
Browse files

prepare release

parent 6a695e1e
Loading
Loading
Loading
Loading
Loading

.gitlab-ci.yml

0 → 100644
+69 −0
Original line number Diff line number Diff line
stages:
  - build
  - release

variables:
  REGISTRY: $CI_REGISTRY
  IMAGE: $CI_REGISTRY_IMAGE

before_script:
  # Log in to GitLab registry for docker builds
  - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin


# --------------------
# Docker builds
# --------------------
.build-template:
  stage: build
  script:
    - |
      if [ -n "$CI_COMMIT_TAG" ]; then
        VERSION="${CI_COMMIT_TAG#v}"   # strip leading v
      else
        VERSION="dev-${CI_COMMIT_SHORT_SHA}"
      fi
    - docker build --target $TARGET \
        -t $IMAGE:$VARIANT \
        -t $IMAGE:${VERSION}-${VARIANT} .
    - docker push $IMAGE:$VARIANT
    - docker push $IMAGE:${VERSION}-${VARIANT}


build:website:
  extends: .build-template
  variables:
    TARGET: website
    VARIANT: website

build:ts:
  extends: .build-template
  variables:
    TARGET: ts
    VARIANT: ts

build:check:
  extends: .build-template
  variables:
    TARGET: check
    VARIANT: check

build:all:
  extends: .build-template
  variables:
    TARGET: all
    VARIANT: all


# --------------------
# Publish to PyPI
# --------------------
publish:pypi:
  stage: release
  image: python:3.13-slim
  before_script:
    - pip install --no-cache-dir uv
  script:
    - uv publish --token $TWINE_PASSWORD
  rules:
    - if: '$CI_COMMIT_TAG'   # only run when a tag is pushed
+16 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ pipx install saref-pipeline

git clone https://labs.etsi.org/rep/saref/saref-pypeline.git
cd saref-pipeline
pip install -e .[check,website]
pip install -e .[check,website,ts]

## Basic usage

@@ -120,3 +120,18 @@ Known limitations:

* [] ts generation: missing general axioms
* [] publish to pypi.

## For maintainers

Docker image tag and library version is automatically computed from git tag.
Use too `bump-my-version` to read the Git history/tags, increment `major`, `minor`, or `patch`, and create the corresponding Git tag.

```
uv tools install bump-my-version
```

Then to tag and push a new version (ex. `minor`):

```
bump-my-version bump minor
```
 No newline at end of file

dockerfile

0 → 100644
+40 −0
Original line number Diff line number Diff line
# ---- Base stage ----
FROM python:3.13-slim AS base

# Install system dependencies for building + runtime
RUN apt-get update && apt-get install -y \
    git \
    libleveldb-dev \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Install uv
RUN pip install --no-cache-dir uv

WORKDIR /app
COPY pyproject.toml uv.lock .python-version ./
COPY src/ src/

RUN uv pip install --system -e .

# ---- Website ----
FROM base AS website
RUN uv pip install --system -e .[website]
ENTRYPOINT ["saref-dev", "website"]

# ---- TS ----
FROM base AS ts
RUN uv pip install --system -e .[ts]
ENTRYPOINT ["saref-dev", "ts"]

# ---- Check ----
FROM base AS check
# Install Java 21
RUN apt-get update && apt-get install -y openjdk-21-jre-headless && rm -rf /var/lib/apt/lists/*
RUN uv pip install --system -e .[check]
ENTRYPOINT ["saref-dev", "check"]

# ---- All ----
FROM check AS all
RUN uv pip install --system -e .[website,ts]
ENTRYPOINT ["saref-dev"]
 No newline at end of file
+9 −2
Original line number Diff line number Diff line
[build-system]
requires = ["setuptools>=61.0"]
requires = ["setuptools>=80", "setuptools-scm[simple]>=8"]
build-backend = "setuptools.build_meta"

[project]
name = "saref-pypeline"
version = "0.1"
dynamic = ["version"]
description = "SAREF pipeline tools"
authors = [
  { name = "Maxime Lefrançois", email = "maxime.lefrancois@emse.fr" }
@@ -24,6 +24,13 @@ dependencies = [
[tool.setuptools.packages.find]
where = ["src"]

[tool.bumpversion]
allow_dirty = false
commit = false
tag = true
tag_name = "v{new_version}"
tag_message = "Bump version: {current_version} → {new_version}"

[project.scripts]
saref-dev = "saref_pypeline.__main__:main"

+50 −7
Original line number Diff line number Diff line
@@ -40,7 +40,8 @@ if TYPE_CHECKING:

logger = logging.getLogger(__name__)
nsmap["v"] = "urn:schemas-microsoft-com:vml"

REGEX_CODE_MD = re.compile(r"^(\s*)`(.*)`(\s*)$")
REGEX_CODE_HTML = re.compile(r"^(.*)</code></pre>\n$")

class ExtractFormat(Enum):
    HTML = auto()
@@ -265,7 +266,7 @@ def extract_run(run: Run, ctx: RunContext):
    text = run.text.replace(" ", " ")

    # extract white space before and after
    before, text, after = re.match(r"^(\W*)(.*?)(\W*)$", text, re.DOTALL).groups()
    before, text, after = re.match(r"^([^a-zA-Z0-9_®<>\.;,]*)(.*?)([^a-zA-Z0-9_®<>\.;,]*)$", text, re.DOTALL).groups()
    if before:
        ctx.buffer_blank.append(before)

@@ -473,7 +474,43 @@ class TS2MDExtractor:
        for block_item in iter_block_items(self.document, text, include_title):
            md = self.extract_block_item(block_item)
            if md:
                md_output.append(md)
                for line in md.split("\n"):
                    md_output.append(line)

        # pre code in examples
        for i, md in enumerate(md_output):
            if i==0:
                continue
            if m0:=re.match(REGEX_CODE_MD, md):
                if m1:=re.match(REGEX_CODE_MD, md_output[i-1]):
                    m1s, m1t, m1e = m1.groups()
                    m0s, m0t, m0e = m0.groups()
                    m1t = m1t.replace("&", "&amp;").replace("<", "&lt;")
                    m0t = m0t.replace("&", "&amp;").replace("<", "&lt;")
                    md_output[i-1] = f"""\n{m1s}<pre><code class="language-turtle">{m1t}{m1e}"""
                    md_output[i] = f"""{m0s}{m0t}{m0e}</code></pre>\n"""
                elif m1:=re.match(REGEX_CODE_HTML, md_output[i-1]):
                    md_output[i-1] = m1.group(1)
                    m0s, m0t, m0e = m0.groups()
                    m0t = m0t.replace("&", "&amp;").replace("<", "&lt;")
                    md_output[i] = f"""{m0s}{m0t}{m0e}</code></pre>\n"""

        # code with newline
        open = False
        for i, md in enumerate(md_output):
            if i==0:
                continue
            if open and (m:=re.match(r"^([^`]*)`(\s*)$", md)):
                open = False
                mt, me = m.groups()
                mt = mt.replace("&", "&amp;").replace("<", "&lt;")
                md_output[i] = f"""{mt}</code></pre>{me}"""
            if not open and (m:=re.match(r"^(\s*)`([^`]*)$", md)):
                open = True
                ms, mt = m.groups()
                mt = mt.replace("&", "&amp;").replace("<", "&lt;")
                md_output[i] = f"""\n{ms}<pre><code class="language-turtle">{mt}"""
                
        return "\n".join(md_output)

    def extract_block_item(self, block_item: Table | Paragraph) -> str:
@@ -595,6 +632,9 @@ class TS2MDExtractor:
    def extract_heading(self, paragraph: Paragraph, prefix: str):
        md = self.extract_inner_content(paragraph)
        if match := re.match(r"^\d+(\.\d+)* *\t(.*)", md):
            if match.group(1)==".0":
                md = "<mark/>" + match.group(2)
            else:
                md = match.group(2)
        elif match := re.match(r"^Annex.*?\n(.*)", md):
            md = match.group(1)
@@ -651,10 +691,13 @@ class TS2MDExtractor:
            # Example
            left, right = md.split("\t", 1)
            content = right.replace("\n", "\n    ")
            return f'!!! example "{left}"\n{content}\n'
            return f'!!! example "{left}"\n    {content}'
        elif md.startswith("["):
            # Reference
            return f"* {md}"
        elif m:=re.match(r"^(\s*)`(.*)`([\s,;\.\(\)\[\]]*)$", md, re.DOTALL):
            # line of code in example
            return f"    `"+ "`\n    `".join(f"{m.group(1)}{m.group(2)}{m.group(3)}".split("\n")) + "`"
        else:
            # last item of abbreviations:
            left, right = md.split("\t", 1)
@@ -759,7 +802,7 @@ class TS2MDExtractor:
        self, paragraph: Paragraph, extract_format: ExtractFormat = ExtractFormat.MD
    ):
        """Bulleted indent 3 (square bullets)"""
        return self.extract_B_plus(paragraph, 8, extract_format)
        return self.extract_B_plus(paragraph, 6, extract_format)

    def extract_BN(
        self, paragraph: Paragraph, extract_format: ExtractFormat = ExtractFormat.MD
@@ -1154,7 +1197,7 @@ class TS2MDExtractor:

def print_admonition(classes: str, title: str, md: str):
    prefix = 4 * " "
    content = md.replace("\n", f"\n{prefix}")
    content = md.replace("\n", f"\n{prefix}").lstrip()
    return f'\n!!! {classes} "{title}"\n{prefix}{content}\n'


Loading