Upload Action
Quick start
Section titled “Quick start”Add the action to a workflow step after your build produces one or more .jar or .zip artifacts. The action uploads those files to Guizhan Resources and creates a new project version through the version creation endpoint.
Minimal example using a local file:
- uses: ybw0014/guizhan-resources-action@v0 with: token: ${{ secrets.GUIZHAN_TOKEN }} project: my-project channel: releases files: build/libs/*.jarAuthentication
Section titled “Authentication”The action calls version creation endpoint on your behalf. Your token must include the project:version:create scope. Organization-owned projects also require the project:version:create organization member permission.
Create a token in your Guizhan Resources account settings and store it as a repository secret (for example, GUIZHAN_TOKEN). The action automatically masks the token in logs.
Reference
Section titled “Reference”uses: ybw0014/guizhan-resources-action@v0domain`https://resources.guizhanss.com/api`API base URL. A bare host such as resources.guizhanss.com is normalized to https://resources.guizhanss.com/api. Trailing slashes are removed.
tokenRequiredAccess token with project:version:create scope.
projectRequiredProject ID or slug.
channelRequiredChannel ID or slug.
filesRequirednoneNewline or comma-separated local paths or glob patterns. At least one of files or artifact-names is required.
artifact-namesRequirednoneNewline or comma-separated GitHub Actions artifact names from the current workflow run. At least one of files or artifact-names is required.
primary-filenoneBasename of the file that should be treated as the primary file. Must match one of the resolved files.
version`GITHUB_REF_NAME`Version string. When omitted, the action derives it from GITHUB_REF_NAME and strips one leading v.
nameresolved `version`Display name for the version.
changelogomitChangelog in Markdown.
changelog-fileomitPath to a UTF-8 file containing the changelog. Leading and trailing whitespace is trimmed. Mutually exclusive with changelog; setting both fails the action.
minecraft-versionsauto/omitComma or newline-separated Minecraft versions. Overrides auto-detection.
platformsauto/omitComma or newline-separated platform IDs. Overrides auto-detection.
dependenciesomitJSON string matching the API dependency format. Fails on invalid JSON. See Dependencies format.
auto-detect-minecraft`true`Infer Minecraft versions from resolved file basenames when explicit input is omitted.
auto-detect-platform`true`Infer platforms from JAR descriptors or basenames when explicit input is omitted.
retry-attempts`2`Total number of upload attempts (including the first) for transient failures (network errors and HTTP 5xx). Must be an integer >= 1.
retry-delay`1000`Base delay in milliseconds between retries, scaled by attempt number. Must be an integer >= 0.
fail-mode`fail`Behavior when a matched file cannot be parsed or yields no detected metadata: fail errors out, warn uploads it without detected metadata, skip excludes it from the upload.
version-idID of the created version.
version-urlDirect URL to the created version page.
uploaded-filesComma-separated list of uploaded file basenames in final order.
api-codeNormalized result code. 0 means success, including a verified idempotent replay of an earlier attempt; otherwise the API error code.
Dependencies format
Section titled “Dependencies format”The dependencies input accepts a JSON array of objects. Each object has a type and exactly one identifier:
| Field | Type | Description |
|---|---|---|
type | required | optional | incompatible | embedded | Relationship to this version. |
version_id | 8-character string | Links to a specific version on Guizhan Resources. |
project_id | 8-character string | Links to a project (any compatible version). |
name | 1–64 visible characters | External dependency display name. May be paired with url. |
url | HTTP(S) URL | Optional homepage or download page for external dependencies. |
Rules:
- Provide exactly one of
version_id,project_id, ornameper entry — more than one or none is rejected. urlis only meaningful alongsidename.- Duplicate identifiers are rejected.
[ { "type": "required", "version_id": "vers1234" }, { "type": "optional", "project_id": "proj1234" }, { "type": "embedded", "name": "Vault", "url": "https://example.com/vault" }]In a workflow file, pass it as a single-line JSON string:
- uses: ybw0014/guizhan-resources-action@v0 with: dependencies: '[{"type":"required","version_id":"vers1234"}]'Local file usage
Section titled “Local file usage”Provide files as paths or glob patterns relative to the repository root. The action resolves globs, rejects directories, and validates file basenames and extensions locally. The API validates file-size and file-count limits.
- uses: ybw0014/guizhan-resources-action@v0 with: token: ${{ secrets.GUIZHAN_TOKEN }} project: my-project channel: releases files: | build/libs/plugin.jar build/distributions/docs.zip primary-file: plugin.jar version: ${{ github.ref_name }} changelog: ${{ github.event.release.body }}Artifact usage
Section titled “Artifact usage”If your build step uploads artifacts with actions/upload-artifact, you can reference those artifact names instead of local paths. The action downloads artifacts from the current workflow run into a temporary directory and treats the contained files as upload sources.
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: ./gradlew build - uses: actions/upload-artifact@v4 with: name: plugin-artifact path: build/libs/*.jar
upload: needs: build runs-on: ubuntu-latest steps: - uses: ybw0014/guizhan-resources-action@v0 with: token: ${{ secrets.GUIZHAN_TOKEN }} project: my-project channel: releases artifact-names: plugin-artifactYou can combine files and artifact-names in the same step. Duplicate basenames across sources are rejected before upload.
Primary file behavior
Section titled “Primary file behavior”The first entry in data.files becomes the primary file for the version. This is the file users receive when they click a generic download link. By default, files are sorted by basename then absolute path, so the order is deterministic.
If you want a specific file to be primary, set primary-file to its basename. The action moves that file to the first position in the upload list. primary-file must exactly match one of the resolved basenames.
Auto-detection behavior
Section titled “Auto-detection behavior”When minecraft-versions or platforms are not provided explicitly, the action can infer them from the resolved files.
- Minecraft versions: Scans file basenames for release patterns such as
1.20.4,1.21, and year-based patterns such as26.1,27.10.2. Deduplicates matches and includes them when non-empty. - Platforms: Inspects
.jarfiles forpaper-plugin.yml(Paper),plugin.yml(Bukkit), and checks basenames forfolia,paper, orspigot. Deduplicates matches and includes them when non-empty.
Explicit inputs always override auto-detection. If detection finds nothing, the optional fields are omitted and the API falls back to the channel defaults.
When a matched file cannot be parsed (for example, a non-ZIP archive) or yields no detected metadata, fail-mode decides what happens: fail (default) fails the action, warn uploads the file without detected metadata, and skip silently excludes it from the upload. When explicit minecraft-versions and platforms fully cover auto-detection, files are not parsed at all.
File filtering and deduplication
Section titled “File filtering and deduplication”Glob patterns and artifact downloads skip unrelated sidecar files (.sha1, .sha256, .md5, .md, .txt, .json checksums and notes). Files listed as literal paths are always uploaded after validation. The same path matched by multiple patterns uploads only once.
Retries and idempotent replay
Section titled “Retries and idempotent replay”Transient failures (network errors, response-body read failures, and HTTP 5xx) are retried up to retry-attempts total attempts with linear backoff (retry-delay scaled by attempt number plus small jitter). Each HTTP request has its own 10-minute timeout. Validation and authentication errors are not retried.
If the API responds with code 5301 (version already exists) — for example after an earlier attempt succeeded but its response was lost — the action fetches the existing version and compares channel (slug case-insensitively), name, changelog, Minecraft versions, platforms, dependencies, and every file’s name, size, SHA-256, and primary flag. Only an exact match is treated as an idempotent success (api-code 0); any mismatch fails the action. Files excluded by fail-mode: skip are also excluded from this comparison.
Troubleshooting
Section titled “Troubleshooting”| Error | Cause | Resolution |
|---|---|---|
400 | Validation failure. Common causes include invalid data JSON, missing required fields, unsupported file types, file count over the limit, or individual files exceeding the size limit. | Check that all required inputs are set, files are .jar or .zip, and file sizes are within limits. Verify dependencies is valid JSON if provided. |
401 | Token is missing, expired, or invalid. | Confirm the token is stored correctly and has not expired. |
403 | Token lacks the project:version:create scope, or the project is organization-owned and your account lacks the organization member permission. | Create a new token with the required scope, or ask the organization owner to grant the permission. |
409 | A version with the same identifier already exists for this project and channel. If it was created by an earlier attempt of this same request, the action verifies it and treats it as success. | Change the version input or delete the existing version first. |
For transient network errors or HTTP 502/503/504, the action retries up to retry-attempts times (default 2 total attempts) with linear backoff based on retry-delay. Validation and authentication errors are not retried.
