@@ -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 Paul W.
|
||||||
|
|
||||||
|
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