diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5946cc299..4ee1b0e22 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,6 +105,22 @@ jobs: uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 with: upload: ${{ env.UPLOAD_CODEQL }} + - name: Upload build zip archive + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f + with: + name: build_zip + path: ./metaschema-cli/target/*metaschema-cli.zip + build-container: + name: Container + permissions: + contents: read + packages: write + attestations: write + id-token: write + needs: build-code + uses: ./.github/workflows/container.yml + with: + push: true build-website: name: Website runs-on: ubuntu-24.04 diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml new file mode 100644 index 000000000..1b9a564b0 --- /dev/null +++ b/.github/workflows/container.yml @@ -0,0 +1,92 @@ +name: Build and Publish Container +on: + workflow_call: + inputs: + push: + description: 'Whether to push the container image to the registry' + required: false + default: false + type: boolean +env: + REGISTRY: ghcr.io + IMAGE_NAME: metaschema-framework/metaschema-cli + # Docs: github.com/docker/metadata-action/?tab=readme-ov-file#typesha + DOCKER_METADATA_PR_HEAD_SHA: true + # https://github.com/docker/metadata-action?tab=readme-ov-file#annotations + DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index +jobs: + build-container: + name: Build Image + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + with: + submodules: recursive + filter: tree:0 + - name: Download build zip + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 + with: + name: build_zip + path: ./metaschema-cli/target + - name: Container image QEMU setup for cross-arch builds + id: image_setup_qemu + uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf + - name: Container image buildx setup for cross-arch builds + id: image_setup_buildx + uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db + with: + platforms: linux/amd64,linux/arm64/v8 + - name: Container image login + id: image_login + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Container image metadata and tag generation + id: image_metadata + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 + with: + images: + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=sha,prefix=,suffix=,format=long + type=ref,event=branch + type=ref,event=tag + type=ref,event=pr + flavor: | + latest=${{ github.ref == 'refs/heads/main' }} + annotations: | + maintainers="Metaschema Community Admin " + org.opencontainers.image.authors="Metaschema Community Admin " + org.opencontainers.image.documentation="https://metaschema.dev" + org.opencontainers.image.source="https://github.com/metaschema-framework/metaschema-java" + org.opencontainers.image.vendor="Metaschema Community" + org.opencontainers.image.title="metaschema-cli" + org.opencontainers.image.description="Metaschema-powered CLI tool" + org.opencontainers.image.licenses="CC0-1.0" + - if: inputs.push + name: Container image registry push + id: image_registry_push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + file: ./Dockerfile.ci + push: true + tags: ${{ steps.image_metadata.outputs.tags }} + labels: ${{ steps.image_metadata.outputs.labels }} + platforms: linux/amd64,linux/arm64/v8 + cache-from: type=gha + cache-to: type=gha,mode=max + - if: inputs.push + name: Container image push attestations + uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.image_registry_push.outputs.digest }} + push-to-registry: true diff --git a/Dockerfile.ci b/Dockerfile.ci new file mode 100644 index 000000000..a20ad4659 --- /dev/null +++ b/Dockerfile.ci @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 +ARG BUILDER_IMAGE=maven:3.9.9-eclipse-temurin-17 +ARG RUNNER_IMAGE=eclipse-temurin:17 + +FROM ${BUILDER_IMAGE} AS builder +RUN apt-get update && apt-get install -y unzip +COPY ./metaschema-cli/target/*metaschema-cli.zip /tmp/metaschema-cli.zip +WORKDIR /tmp +RUN unzip /tmp/metaschema-cli.zip -d /opt/metaschema-cli +RUN chmod +x /opt/metaschema-cli/bin/metaschema-cli + +FROM ${RUNNER_IMAGE} AS runner +COPY --from=builder /opt/metaschema-cli /opt/metaschema-cli +RUN groupadd -r metaschema && \ + useradd -r -g metaschema -s /bin/false metaschema && \ + chown -R metaschema:metaschema /opt/metaschema-cli && \ + mkdir -p /app && \ + chown metaschema:metaschema /app +WORKDIR /app +USER metaschema +RUN /opt/metaschema-cli/bin/metaschema-cli --version +ENTRYPOINT [ "/opt/metaschema-cli/bin/metaschema-cli" ] diff --git a/Dockerfile.local b/Dockerfile.local new file mode 100644 index 000000000..a2d7d0f37 --- /dev/null +++ b/Dockerfile.local @@ -0,0 +1,49 @@ +# syntax=docker/dockerfile:1 +ARG BUILDER_IMAGE=maven:3.9.9-eclipse-temurin-17 +ARG RUNNER_IMAGE=eclipse-temurin:17 + +FROM ${BUILDER_IMAGE} AS builder +ARG BUILDER_JDK_VENDOR=temurin +ARG BUILDER_JDK_MAJOR_VERSION=17 +ARG BUILDER_JDK_HOME_PATH=/opt/java/openjdk +ADD . /usr/local/src +WORKDIR /usr/local/src +RUN apt-get update && apt-get install -y unzip +RUN < /root/.m2/toolchains.xml << XMLEOF + + + + jdk + + ${BUILDER_JDK_VENDOR} + ${BUILDER_JDK_MAJOR_VERSION} + + + ${BUILDER_JDK_HOME_PATH} + + + +XMLEOF +EOF +RUN mvn -B -e -Prelease package +RUN find /usr/local/src/metaschema-cli/target \ + -iname 'metaschema-cli-*metaschema-cli.zip' \ + -exec cp {} /tmp/metaschema-cli.zip \; +RUN mkdir -p /opt/metaschema-cli +RUN unzip /tmp/metaschema-cli.zip -d /opt/metaschema-cli +RUN chmod +x /opt/metaschema-cli/bin/metaschema-cli + +FROM ${RUNNER_IMAGE} AS runner +COPY --from=builder /opt/metaschema-cli /opt/metaschema-cli +RUN groupadd -r metaschema && \ + useradd -r -g metaschema -s /bin/false metaschema && \ + chown -R metaschema:metaschema /opt/metaschema-cli && \ + mkdir -p /app && \ + chown metaschema:metaschema /app +WORKDIR /app +USER metaschema +RUN /opt/metaschema-cli/bin/metaschema-cli --version +ENTRYPOINT [ "/opt/metaschema-cli/bin/metaschema-cli" ] + diff --git a/README.md b/README.md index 3213be39f..7df3bc1f1 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,68 @@ git clone --recurse-submodules https://github.com/metaschema-framework/metaschem mvn install ``` +## Installing the CLI tool + +The maintainers provide developers of Metaschema-enabled tools a CLI tool from this repository to dynamically validate Metaschema models themselves, content based on developer-provided models, and format conversion for models and content between supported data formats (e.g. JSON, XML, and YAML). There are multiple ways to install this CLI tool. + +1. Build the project locally with Maven. +1. Download a developer snapshot from the Metaschema Framework repository for pre-release builds. +1. Download the official releases from the official Maven Central. +1. Download an OCI-conformant container image from the [GitHub Container Registry (ghcr.io)](https://ghcr.io) for use with `docker`, `podman`, Kubernetes, or other container orchestration platforms. + +### Build the project locally with Maven + +To build the project locally, follow the [instructions above](#building) that explain how to build and install project packages, including the CLI, with Maven (`mvn`). + +### Download pre-built snapshot release + +To download, unzip, and install a pre-built snapshot release (a developer build that is not an official release), please visit [the GitHub `metaschema-framework/maven2` repository](https://github.com/metaschema-framework/maven2/tree/main/dev/metaschema/java/metaschema-cli/) to download a `.bz2`, `.gz`, or `.zip` archive. + +```sh +# Visit https://github.com/metaschema-framework/maven2/commits/main/dev/metaschema/java/metaschema-cli +# Adjust the value for CURRENT_SNAPSHOT_PATH for most recently committed artifact by folder and file name. +export CURRENT_SNAPSHOT_PATH="3.0.0.M1-SNAPSHOT/metaschema-cli-3.0.0.M1-20251213.151427-29-metaschema-cli.zip" +# Download the zip archive to /tmp +cd /tmp +curl -L -O "https://github.com/metaschema-framework/maven2/raw/refs/heads/main/dev/metaschema/java/metaschema-cli/${CURRENT_SNAPSHOT_PATH}" +# Extract zip archive to /opt/metaschema-cli +# You might need sudo for permission to write files to this path +sudo unzip /tmp/metaschema-cli-*-metaschema-cli.zip -d /opt/metaschema-cli +# Now add this installation directory to the path +export PATH="${PATH}:/opt/metaschema-cli" +# Run the CLI to test it is properly installed +metaschema-cli --version +``` + +### Download a pre-built official release from Maven Central + +You can also use Maven to download a pre-built official release from Maven Central using the Maven (`mvn`) CLI tool, unzipping the archive, and then adding that directory to your path. + +```sh +# Download the zip archive of the latest release to /tmp +mvn \ + org.apache.maven.plugins:maven-dependency-plugin:LATEST:copy \ + -DoutputDirectory=/tmp \ + -DremoteRepositories=https://repo1.maven.org/maven2 \ + -Dartifact=dev.metaschema.java:metaschema-cli:LATEST:zip:metaschema-cli +# Extract zip archive to /opt/metaschema-cli +# You might need sudo for permission to write files to this path +sudo unzip "/tmp/*metaschema-cli.zip" -d /opt/metaschema-cli +# Now add this installation directory to the path +export PATH="${PATH}:/opt/metaschema-cli" +# Run the CLI to test it is properly installed +metaschema-cli --version +``` + +### Download container image + +You can also download pre-release and official release versions of the CLI as an OCI-conformant image with `docker`, `podman`, or other tools. + +```sh +docker pull ghcr.io/metaschema-framework/metaschema-cli:latest +docker run -it ghcr.io/metaschema-framework/metaschema-cli:latest --version +``` + ## Relationship to prior work The contents of this repository is based on work from the [Metaschema Java repository](https://github.com/usnistgov/metaschema-java/) maintained by the National Institute of Standards and Technology (NIST), the [contents of which have been dedicated in the worldwide public domain](https://github.com/usnistgov/metaschema-java/blob/1a496e4bcf905add6b00a77a762ed3cc31bf77e6/LICENSE.md) using the [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) public domain dedication. This repository builds on this prior work, maintaining the [CCO license](https://github.com/metaschema-framework/metaschema-java/blob/main/LICENSE.md) on any new works in this repository.