diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..30315df --- /dev/null +++ b/.dockerignore @@ -0,0 +1,17 @@ +# A whitelist of files that should be included into Docker. +# Put an exclamation mark before everything to include. + +# Ignore everything +* + +# Allow the source code folders +!/src/ +!/wit/ +!/vine.toml + +# Allow build.rs or git sha +!/.git + +# Dependencies +!Cargo.lock +!Cargo.toml diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..8d7f6bf --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ + + +## Description + +## Testing + +Please follow our [Coding Guidelines](https://github.com/Pumpkin-MC/Pumpkin/blob/master/CONTRIBUTING.md#coding-guidelines) diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..37c3c5e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for more information: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: weekly + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..8054fc6 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,150 @@ +# https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners +name: deploy-docker-image + +env: + REGISTRY: ghcr.io + GITHUB_REPOSITORY: ${{ github.repository }} + +on: + push: + branches: + - "master" + workflow_dispatch: + +jobs: + docker-build-deploy: + if: github.repository == 'Pumpkin-MC/Vine' + permissions: + contents: read + packages: write + attestations: write + id-token: write + + strategy: + matrix: + include: + - os: ubuntu-26.04-arm + platform: linux/arm64 + - os: ubuntu-latest + platform: linux/amd64 + + runs-on: ${{matrix.os}} + + steps: + - name: Set lowercase repository name + run: | + echo "REGISTRY_IMAGE=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} + + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Checkout + uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Login to GitHub CR + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract Metadata + id: meta + uses: docker/metadata-action@v6 + with: + images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} + + - name: Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Build and Push + id: build + uses: docker/build-push-action@v7 + with: + context: . + platforms: ${{ matrix.platform }} + labels: ${{ steps.meta.outputs.labels }} + tags: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} + outputs: type=image,push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v7 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + if: github.repository == 'Pumpkin-MC/Vine' + permissions: + contents: read + packages: write + attestations: write + id-token: write + runs-on: ubuntu-latest + needs: + - docker-build-deploy + steps: + - name: Set lowercase repository name + run: | + echo "REGISTRY_IMAGE=${GITHUB_REPOSITORY,,}" >> ${GITHUB_ENV} + + - name: Checkout + uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Download Digests + uses: actions/download-artifact@v8 + with: + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true + + - name: Extract Versions + id: versions + run: | + VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml) + echo "VINE_VERSION=$VERSION" >> $GITHUB_ENV + + - name: Login to GitHub CR + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Extract Metadata + id: meta + uses: docker/metadata-action@v6 + with: + images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} + tags: | + type=ref,event=branch + type=raw,value=latest + type=sha + type=raw,value=${{ env.VINE_VERSION }} + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f254a35 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,165 @@ +name: Release + +on: + push: + tags: + - "*" + - "!nightly" + - "!nightly*" + workflow_dispatch: + inputs: + tag_name: + description: "Release Tag name (optional, defaults to Cargo.toml version)" + required: false + type: string + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: "-Dwarnings" + +jobs: + build_release: + name: Build & Sign Release + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: + [ + ubuntu-latest, + ubuntu-26.04-arm, + windows-latest, + windows-11-arm, + macos-latest, + ] + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - uses: Swatinem/rust-cache@v2 + + - name: Install musl-tools (Linux only) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y musl-tools + + - name: Build Release + shell: bash + run: | + cargo build --verbose --release + if [ "${{ runner.os }}" == "Linux" ]; then + if [ "${{ runner.arch }}" == "X64" ]; then + TARGET="x86_64-unknown-linux-musl" + elif [ "${{ runner.arch }}" == "ARM64" ]; then + TARGET="aarch64-unknown-linux-musl" + fi + rustup target add "$TARGET" + cargo build --verbose --release --target "$TARGET" + fi + + - name: Prepare artifacts + shell: bash + run: | + mkdir -p dist + EXT="" + if [ "${{ runner.os }}" == "Windows" ]; then EXT=".exe"; fi + cp "target/release/vine$EXT" "dist/vine-${{ runner.arch }}-${{ runner.os }}$EXT" + if [ "${{ runner.os }}" == "Linux" ]; then + if [ "${{ runner.arch }}" == "X64" ]; then + TARGET="x86_64-unknown-linux-musl" + elif [ "${{ runner.arch }}" == "ARM64" ]; then + TARGET="aarch64-unknown-linux-musl" + fi + cp "target/$TARGET/release/vine" "dist/vine-${{ runner.arch }}-${{ runner.os }}-musl" + fi + + - name: Upload unsigned executable for SignPath (Windows only) + if: runner.os == 'Windows' && env.SIGNPATH_API_TOKEN != '' + id: upload_unsigned + uses: actions/upload-artifact@v7 + with: + name: unsigned-${{ runner.arch }}-${{ runner.os }} + path: dist/vine-* + retention-days: 1 + + - name: Submit SignPath signing request (Windows only) + if: runner.os == 'Windows' && env.SIGNPATH_API_TOKEN != '' + uses: signpath/github-action-submit-signing-request@v2 + with: + api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' + organization-id: '${{ secrets.SIGNPATH_ORGANIZATION_ID }}' + project-slug: '${{ secrets.SIGNPATH_PROJECT_SLUG }}' + signing-policy-slug: '${{ secrets.SIGNPATH_RELEASE_SIGNING_POLICY_SLUG || secrets.SIGNPATH_SIGNING_POLICY_SLUG }}' + github-artifact-id: '${{ steps.upload_unsigned.outputs.artifact-id }}' + wait-for-completion: true + output-artifact-directory: dist/signed/ + + - name: Overwrite with signed version (Windows only) + if: runner.os == 'Windows' && env.SIGNPATH_API_TOKEN != '' + shell: bash + run: | + cp dist/signed/* dist/ + rm -rf dist/signed/ + + - name: Export executable + uses: actions/upload-artifact@v7 + with: + name: vine-${{ runner.arch }}-${{ runner.os }} + compression-level: 9 + path: dist/vine-* + + publish_release: + name: Publish GitHub Release + permissions: + contents: write + needs: [build_release] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + + - name: Determine tag name + id: tag + shell: bash + run: | + if [ -n "${{ github.event.inputs.tag_name }}" ]; then + TAG="${{ github.event.inputs.tag_name }}" + elif [ "${{ github.ref_type }}" == "tag" ]; then + TAG="${{ github.ref_name }}" + else + VERSION=$(awk -F '"' '/^version/ {print $2}' Cargo.toml) + TAG="${VERSION}" + fi + echo "tag_name=${TAG}" >> $GITHUB_OUTPUT + echo "Determined release tag: ${TAG}" + + - name: Download prebuilt binary artifacts + uses: actions/download-artifact@v8 + with: + pattern: "vine-*" + path: dist/ + merge-multiple: true + + - name: Generate Checksums + shell: bash + run: | + cd dist + sha256sum vine-* > checksums.sha256 + cat checksums.sha256 + + - name: Create GitHub Release + uses: softprops/action-gh-release@v3 + with: + tag_name: ${{ steps.tag.outputs.tag_name }} + name: Release ${{ steps.tag.outputs.tag_name }} + files: | + dist/vine* + dist/checksums.sha256 + generate_release_notes: true diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..57b7145 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,229 @@ +name: Cargo Build, Test, and Linting + +on: + push: + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: "-Dwarnings" + +jobs: + format: + name: Check formatting + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - run: rustup component add rustfmt + - uses: Swatinem/rust-cache@v2 + - run: cargo fmt --check + + machete: + name: Detect unused dependencies + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - uses: bnjbvr/cargo-machete@main + + clippy_debug: + name: Run lints (debug) + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - run: rustup component add clippy + - uses: Swatinem/rust-cache@v2 + - name: Clippy (debug) + run: cargo clippy --all-targets --all-features + + clippy_release: + name: Run lints (release) + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - run: rustup component add clippy + - uses: Swatinem/rust-cache@v2 + - name: Clippy (release) + run: cargo clippy --release --all-targets --all-features + + build_and_test: + name: Build project and test + runs-on: ${{ matrix.os }} + needs: [format, machete, clippy_debug, clippy_release] + strategy: + matrix: + os: + [ + ubuntu-latest, + ubuntu-26.04-arm, + windows-latest, + windows-11-arm, + macos-latest, + ] + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - uses: taiki-e/install-action@nextest + - uses: Swatinem/rust-cache@v2 + - name: Cargo nextest + run: cargo nextest run --verbose + - name: Cargo doctest + run: cargo test --doc --verbose + + build_release: + name: Build project in release + runs-on: ${{ matrix.os }} + needs: [build_and_test] + strategy: + matrix: + os: + [ + ubuntu-latest, + ubuntu-26.04-arm, + windows-latest, + windows-11-arm, + macos-latest, + ] + toolchain: + - stable + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Checkout Pumpkin dependency + shell: bash + run: git clone --depth 1 https://github.com/Pumpkin-MC/Pumpkin.git ../Pumpkin + - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} + - uses: Swatinem/rust-cache@v2 + + - name: Install musl-tools (Linux only) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y musl-tools + + - name: Build Release + shell: bash + run: | + cargo build --verbose --release + if [ "${{ runner.os }}" == "Linux" ]; then + if [ "${{ runner.arch }}" == "X64" ]; then + TARGET="x86_64-unknown-linux-musl" + elif [ "${{ runner.arch }}" == "ARM64" ]; then + TARGET="aarch64-unknown-linux-musl" + fi + rustup target add "$TARGET" + cargo build --verbose --release --target "$TARGET" + fi + + - name: Prepare artifacts + shell: bash + run: | + mkdir -p dist + EXT="" + if [ "${{ runner.os }}" == "Windows" ]; then EXT=".exe"; fi + cp "target/release/vine$EXT" "dist/vine-${{ runner.arch }}-${{ runner.os }}$EXT" + if [ "${{ runner.os }}" == "Linux" ]; then + if [ "${{ runner.arch }}" == "X64" ]; then + TARGET="x86_64-unknown-linux-musl" + elif [ "${{ runner.arch }}" == "ARM64" ]; then + TARGET="aarch64-unknown-linux-musl" + fi + cp "target/$TARGET/release/vine" "dist/vine-${{ runner.arch }}-${{ runner.os }}-musl" + fi + + - name: Export executable + uses: actions/upload-artifact@v7 + with: + name: vine-${{ runner.arch }}-${{ runner.os }} + compression-level: 9 + path: dist/vine-* + + draft_release: + permissions: + contents: write + needs: [build_release] + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v7 + with: + submodules: recursive + - name: Download prebuilt binary artifacts + uses: actions/download-artifact@v8 + with: + pattern: "**/vine-*" + path: dist/ + merge-multiple: true + - name: Generate release notes + run: | + tree dist/ || ls -la dist/ + echo "From commit: $(git rev-parse --short HEAD)" > dist/RELEASE.md + echo "Generated on: $(date -u +"%Y-%m-%d %H:%M") UTC" >> dist/RELEASE.md + cat dist/RELEASE.md + + - name: Update the nightly tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag --force nightly && git push --force origin tag nightly + + - name: Draft a nightly github release + uses: softprops/action-gh-release@v3 + with: + prerelease: true + files: dist/vine* + tag_name: nightly + name: Nightly Build + body_path: dist/RELEASE.md diff --git a/.github/workflows/typos.yml b/.github/workflows/typos.yml new file mode 100644 index 0000000..762e6f6 --- /dev/null +++ b/.github/workflows/typos.yml @@ -0,0 +1,24 @@ +name: Spelling + +permissions: + contents: read + +on: + push: + pull_request: + workflow_dispatch: + +env: + CLICOLOR: 1 + +jobs: + spelling: + name: Spell Check with Typos + runs-on: ubuntu-latest + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v7 + with: + submodules: recursive + - name: Spell Check Repo + uses: crate-ci/typos@v1.50.0 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d597559 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM alpine:3.24 + +ARG TARGETARCH +ARG VINE_TAG=nightly + +RUN apk add --no-cache curl ca-certificates && \ + case "${TARGETARCH}" in \ + "amd64") BIN_ARCH="X64" ;; \ + "arm64") BIN_ARCH="ARM64" ;; \ + *) echo "Unsupported architecture: ${TARGETARCH}" && exit 1 ;; \ + esac && \ + curl -fsSL "https://github.com/Pumpkin-MC/Vine/releases/download/${VINE_TAG}/vine-${BIN_ARCH}-Linux-musl" \ + -o /usr/local/bin/vine && \ + chmod +x /usr/local/bin/vine && \ + apk del curl + +RUN addgroup -g 2613 vine && \ + adduser -u 2613 -G vine -D -h /vine vine && \ + chown -R vine:vine /vine + +WORKDIR /vine +USER vine:vine + +ENV RUST_BACKTRACE=1 +EXPOSE 25565 +EXPOSE 19132/udp + +ENTRYPOINT [ "vine" ] + +HEALTHCHECK --interval=30s --timeout=3s --retries=3 \ + CMD nc -z 127.0.0.1 25565 || exit 1 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9616adb --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +services: + vine: + # Make sure to change the tag to the vine version you want to use. + # https://github.com/Pumpkin-MC/Vine/pkgs/container/vine/versions?filters%5Bversion_type%5D=tagged + #image: ghcr.io/pumpkin-mc/vine:master + build: . + ports: + - "25565:25565" + - "19132:19132/udp" + volumes: + - ./data:/vine + # Use the following, if you want to make your config immutable + #- ./vine.toml:/vine/vine.toml:ro + security_opt: + - no-new-privileges:true + restart: unless-stopped + stdin_open: true + tty: true + cap_drop: + - ALL + read_only: false diff --git a/egg-vine.json b/egg-vine.json new file mode 100644 index 0000000..ef1ad35 --- /dev/null +++ b/egg-vine.json @@ -0,0 +1,73 @@ +{ + "_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO", + "meta": { + "version": "PTDL_v2", + "update_url": null + }, + "exported_at": "2026-09-08T18:00:00+00:00", + "name": "Vine", + "author": "lilalexmed@proton.me", + "description": "Vine is a high-performance, lightweight, multi-version Minecraft proxy built entirely in Rust, offering sub-millisecond packet routing, WASM plugin support, and modern protocol compatibility.", + "features": null, + "docker_images": { + "Alpine": "ghcr.io/pterodactyl/yolks:alpine", + "Debian": "ghcr.io/pterodactyl/yolks:debian" + }, + "file_denylist": [], + "startup": "./vine", + "config": { + "files": "{\r\n \"vine.toml\": {\r\n \"parser\": \"file\",\r\n \"find\": {\r\n \"bind_address = \\\"0.0.0.0:25565\\\"\": \"bind_address = \\\"0.0.0.0:{{server.build.default.port}}\\\"\"\r\n }\r\n }\r\n}", + "startup": "{\r\n \"done\": \"Vine Minecraft Proxy is listening on\"\r\n}", + "logs": "{}", + "stop": "stop" + }, + "scripts": { + "installation": { + "script": "#!/bin/ash\r\nset -eux\r\n\r\napk add --no-cache curl jq\r\nmkdir -p /mnt/server\r\ncd /mnt/server\r\n\r\nARCH=$(uname -m)\r\ncase \"$ARCH\" in\r\n x86_64|amd64)\r\n VINE_ARCH=\"X64\"\r\n ;;\r\n aarch64|arm64)\r\n VINE_ARCH=\"ARM64\"\r\n ;;\r\n *)\r\n echo \"Unsupported architecture: $ARCH\"\r\n exit 1\r\n ;;\r\nesac\r\n\r\nBINARY_NAME=\"vine-${VINE_ARCH}-Linux-musl\"\r\n\r\nif [ -n \"${DOWNLOAD_URL:-}\" ]; then\r\n URL=\"$DOWNLOAD_URL\"\r\nelif [ \"${VERSION:-nightly}\" = \"latest\" ] || [ \"${VERSION:-nightly}\" = \"nightly\" ]; then\r\n URL=\"https://github.com/${GITHUB_PACKAGE:-Pumpkin-MC/Vine}/releases/download/nightly/${BINARY_NAME}\"\r\nelse\r\n URL=\"https://github.com/${GITHUB_PACKAGE:-Pumpkin-MC/Vine}/releases/download/${VERSION}/${BINARY_NAME}\"\r\nfi\r\n\r\necho \"Downloading Vine from: $URL\"\r\ncurl -fsSL \"$URL\" -o /mnt/server/vine\r\nchmod +x /mnt/server/vine\r\n\r\n# Quickly start and kill proxy to generate initial configuration if not present\r\nif [ ! -f /mnt/server/vine.toml ]; then\r\n timeout 2 ./vine || true\r\nfi", + "container": "ghcr.io/pterodactyl/installers:alpine", + "entrypoint": "ash" + } + }, + "variables": [ + { + "name": "Rust backtrace", + "description": "\"0\" -> No backtrace is generated. This is the default behavior.\r\n\"1\" -> Generates a minimal backtrace showing only relevant information about where the panic occurred.\r\n\"full\" -> Generates a detailed backtrace, showing all frames leading to the panic, including functions in the Rust standard library and dependencies.", + "env_variable": "RUST_BACKTRACE", + "default_value": "1", + "user_viewable": true, + "user_editable": true, + "rules": "required|in:1,0,full", + "field_type": "text" + }, + { + "name": "Vine Version", + "description": "The version of Vine to install. Options: 'nightly', 'latest', or a specific release tag (e.g. 'v0.1.0').\r\nScope: installation", + "env_variable": "VERSION", + "default_value": "nightly", + "user_viewable": true, + "user_editable": true, + "rules": "required|string|max:64", + "field_type": "text" + }, + { + "name": "GitHub Repository", + "description": "GitHub repository in 'owner/repo' format to download releases from. Useful if you are using a fork.\r\nScope: installation", + "env_variable": "GITHUB_PACKAGE", + "default_value": "Pumpkin-MC/Vine", + "user_viewable": true, + "user_editable": true, + "rules": "required|string|max:128", + "field_type": "text" + }, + { + "name": "Direct Download URL", + "description": "Direct URL to download the Vine binary from. If provided, this overrides VERSION and GITHUB_PACKAGE.\r\nScope: installation", + "env_variable": "DOWNLOAD_URL", + "default_value": "", + "user_viewable": true, + "user_editable": true, + "rules": "nullable|string", + "field_type": "text" + } + ] +} diff --git a/typos.toml b/typos.toml new file mode 100644 index 0000000..678b1e7 --- /dev/null +++ b/typos.toml @@ -0,0 +1,10 @@ +[files] +extend-exclude = ["assets/"] + +[default.extend-words] +handled = "handled" +received = "received" +ba = "ba" +fo = "fo" +undescore = "undescore" +replaceables = "replaceables"