@@ -0,0 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.sh]
|
||||
indent_size = 2
|
||||
@@ -0,0 +1,23 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
smoke:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: install deps
|
||||
run: sudo apt-get update && sudo apt-get install -y jq
|
||||
|
||||
- name: bash syntax
|
||||
run: bash -n bin/shx-upload tests/smoke.sh
|
||||
|
||||
- name: smoke test
|
||||
run: ./tests/smoke.sh
|
||||
@@ -0,0 +1,26 @@
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
package:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: stage artifact
|
||||
run: |
|
||||
mkdir -p dist
|
||||
cp bin/shx-upload dist/shx-upload
|
||||
chmod +x dist/shx-upload
|
||||
tar -C dist -czf shx-helper-${GITHUB_REF_NAME}.tar.gz shx-upload
|
||||
|
||||
- name: upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: shx-helper-${{ github.ref_name }}
|
||||
path: shx-helper-${{ github.ref_name }}.tar.gz
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# local env / secrets
|
||||
.env
|
||||
.env.*
|
||||
*.local
|
||||
|
||||
# editor / os
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# test / temp
|
||||
/tmp/
|
||||
artifacts/
|
||||
*.tmp
|
||||
*.log
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Luna
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,9 @@
|
||||
.PHONY: test smoke lint
|
||||
|
||||
test: smoke
|
||||
|
||||
smoke:
|
||||
./tests/smoke.sh
|
||||
|
||||
lint:
|
||||
bash -n bin/shx-upload tests/smoke.sh
|
||||
@@ -0,0 +1,55 @@
|
||||
# shx-helper
|
||||
|
||||
tiny helper repo for uploads to the SHX Zipline instance.
|
||||
|
||||
## what it includes
|
||||
|
||||
- `bin/shx-upload` - upload one or more files to Zipline
|
||||
- `.gitea/workflows/ci.yml` - basic CI for syntax + smoke tests
|
||||
- `.gitea/workflows/release.yml` - tag build artifact packaging
|
||||
- `tests/smoke.sh` - local smoke test with mocked network calls
|
||||
|
||||
## requirements
|
||||
|
||||
- `bash`
|
||||
- `curl`
|
||||
- `jq` for normal output mode
|
||||
|
||||
## env
|
||||
|
||||
loaded from `/root/.openclaw/.env` by default:
|
||||
|
||||
- `SHX_URL=https://shx.reversed.dev`
|
||||
- `SHX_TOKEN=...` ← required for uploads
|
||||
|
||||
optional fallback:
|
||||
|
||||
- `ZIPLINE_TOKEN=...`
|
||||
|
||||
## usage
|
||||
|
||||
```bash
|
||||
/root/projects/shx-helper/bin/shx-upload ./file.gif
|
||||
/root/projects/shx-helper/bin/shx-upload ./a.png ./b.mp4
|
||||
/root/projects/shx-helper/bin/shx-upload --json ./file.gif
|
||||
/root/projects/shx-helper/bin/shx-upload --help
|
||||
```
|
||||
|
||||
## local checks
|
||||
|
||||
```bash
|
||||
make lint
|
||||
make test
|
||||
```
|
||||
|
||||
## release flow
|
||||
|
||||
push a tag like `v0.1.0` to trigger the release packaging workflow.
|
||||
|
||||
## notes
|
||||
|
||||
- username/password are for dashboard login only
|
||||
- actual uploads use a Zipline API token
|
||||
- docs: https://zipline.diced.sh/docs
|
||||
- upload endpoint ref: https://v3.zipline.diced.sh/docs/api/upload
|
||||
- shell uploader guide: https://zipline.diced.sh/docs/guides/uploaders/shell-script
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ENV_FILE="${SHX_ENV_FILE:-/root/.openclaw/.env}"
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
set -a
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
fi
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
shx-upload <file> [more files...]
|
||||
shx-upload --json <file>
|
||||
|
||||
Env:
|
||||
SHX_URL Base URL, e.g. https://shx.reversed.dev
|
||||
SHX_TOKEN Zipline API token from the dashboard
|
||||
|
||||
Notes:
|
||||
- Username/password are only for dashboard login.
|
||||
- Uploads use an API token.
|
||||
EOF
|
||||
}
|
||||
|
||||
want_json=0
|
||||
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--json" ]]; then
|
||||
want_json=1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: "${SHX_URL:=}"
|
||||
: "${SHX_TOKEN:=${ZIPLINE_TOKEN:-}}"
|
||||
|
||||
if [[ -z "$SHX_URL" ]]; then
|
||||
echo "error: SHX_URL is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$SHX_TOKEN" ]]; then
|
||||
cat >&2 <<EOF
|
||||
error: SHX_TOKEN is not set
|
||||
|
||||
Create one in the Zipline dashboard, then add it to $ENV_FILE like:
|
||||
SHX_TOKEN=your_token_here
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
upload_one() {
|
||||
local file="$1"
|
||||
if [[ ! -f "$file" ]]; then
|
||||
echo "error: file not found: $file" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
local response
|
||||
response="$(curl -fsS \
|
||||
-H "authorization: $SHX_TOKEN" \
|
||||
"$SHX_URL/api/upload" \
|
||||
-F "file=@$file")"
|
||||
|
||||
if [[ $want_json -eq 1 ]]; then
|
||||
printf '%s\n' "$response"
|
||||
else
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
echo "error: jq is required unless --json is used" >&2
|
||||
return 1
|
||||
fi
|
||||
printf '%s\n' "$response" | jq -r 'if .files then .files[] else . end'
|
||||
fi
|
||||
}
|
||||
|
||||
status=0
|
||||
for file in "$@"; do
|
||||
if ! upload_one "$file"; then
|
||||
status=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $status
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
workdir="$(mktemp -d)"
|
||||
trap 'rm -rf "$workdir"' EXIT
|
||||
|
||||
cat >"$workdir/.env" <<'EOF'
|
||||
SHX_URL=https://shx.example
|
||||
SHX_TOKEN=test-token
|
||||
EOF
|
||||
|
||||
mkdir -p "$workdir/bin"
|
||||
cat >"$workdir/bin/curl" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf '%s\n' '{"files":["https://shx.example/mock-file"]}'
|
||||
EOF
|
||||
chmod +x "$workdir/bin/curl"
|
||||
|
||||
cat >"$workdir/bin/jq" <<'EOF'
|
||||
#!/usr/bin/env python3
|
||||
import json, sys
|
||||
payload = json.load(sys.stdin)
|
||||
for item in payload.get("files", []):
|
||||
print(item)
|
||||
EOF
|
||||
chmod +x "$workdir/bin/jq"
|
||||
|
||||
touch "$workdir/demo.txt"
|
||||
|
||||
PATH="$workdir/bin:$PATH" \
|
||||
SHX_ENV_FILE="$workdir/.env" \
|
||||
"$repo_root/bin/shx-upload" "$workdir/demo.txt" >"$workdir/out.txt"
|
||||
|
||||
grep -Fx 'https://shx.example/mock-file' "$workdir/out.txt"
|
||||
|
||||
echo 'smoke ok'
|
||||
Reference in New Issue
Block a user