SuperAPI AI Directory

huawei-cloud-publish-work-to-gallery

General & other

View repository

Updated 10-15 22:15

About this skill

Publish Work to Gallery

Publish the work to the Huawei Cloud University Operations Platform.For deterministic subtasks, call the built-in script first(single entry, fail-fast, built-in --help), stdout/exit code is the basis for judgment. Only when the script reports an error, check references/troubleshooting.md。

Pipeline

Step 1 (workDir, domainID, STS)
Step 2 (port→变量, envUrl→变量)              ← 依赖 Step 1
  ├── Step 3 (gitUrl, gitBranch, workName)   ← 只依赖 workDir
  ├── Step 5 (introduction, camps)           ← 只依赖 workDir + STS
  ├── Step 4 (coverImage)                    ← 依赖 port + workName
  └── Step 6 (detailZip)                     ← 依赖 workName + 代码分析
Step 7 (trainingCampId)                      ← 依赖 Step 5 camps
Step 8 (publish)                             ← 依赖以上全部

Parallel (after Step 2 completes):Step 3/4/5/6 Independent of each other, all four run in parallel(take the longest path Step 4 ~90s, instead of serial ~160s). Within Step 4 preflight + ensure-utf8 then parallel.

Variables run throughout:port/workName/envUrl Once determined at the earliest step, it is passed as a variable through the whole flow; hardcoding is prohibited (the tunnel URL contains port, and when the port changes, envUrl changes accordingly).

Execution model:① Script contract first——judge by stdout success signal,zero source code reading on the success path; only on failure 脚本提示 → troubleshooting 对应节 → grep 脚本源码 check level by level ② Do not manually bypass the gate (publish-work.mjs built-in verifyGates() re-check) ③ Network timeout is uniformly 3s ④ detect-env.mjs After determining the platform, only read the reference for the corresponding platform (navigate by directory, do not read everything) ⑤ Merge bash calls with no dependencies: use ; to chain into one command, reducing tool round trips (~1-2s each).

Script contract quick reference

Step Script/Command Success signal (exit 0 and) Failure (exit 1; 2=parameter error)
Precondition api.mjs GET /v1/gallery/announcements/current --prefix open-api-guest stdout first line #status=200 Timeout/connection refused → prompt to troubleshoot the network
Precondition node <skill>/scripts/check-version.mjs(automatically reads its own version + requests the remote version, parses internally, stdout only status line) exit 0 and first line status=ok/status=skip exit 1 (first line status=outdated + upgrade text issued by the platform) → prompt the user to upgrade as-is, stop publishing
5/7 api.mjs GET "/v1/gallery/camps" --creds-file <json> --fields "id,name,school,status,startsAt,endsAt" #status=200(--fields projection reduces tokens) 401 → refresh STS
1 scan-projects.mjs stdout #project <n> <path> <type> exit 1=no candidate
1 resolve-domain.mjs [--hcloud <exe>] stdout #domain=<id> name=<name> exit 1=hcloud failure (stderr contains troubleshooting guidance)
1 gen_sts.py --account <id> writes sts-creds.json(contains _refresh)+sts-creds.sh see [troubleshooting#domain-id-resolution-issues]
3 strip-git-credential.mjs "<rawUrl>" stdout=safe URL (starts with https://, ends with .git, no @) @/not https/not .git → stop publishing
3 ensure-gitcode-credential.mjs #credential=found or #credential=missing(exit 0) exit 1=Windows has no credentials and skill is not installed (stderr contains install command)
3 extract-workname.mjs <workDir> stdout #name=<name> source=<来源> exit 1=workDir does not exist
4 preflight.sh / preflight.ps1 writes font-gate-ok(ok=true gate=preflight) screenshot/cover/chartprohibited
4 ensure-utf8.mjs <dir> writes utf8-gate-ok encoding not UTF-8 → screenshots prohibited
4 build-cover.mjs --url … --project-dir … --title … --out … stdout one line #cover=… layout=… multi=… exit 1 → any of screenshot/validation/composition failed, stderr details
4 screenshot_guard.py http://… --out <png> --quiet writes screenshot-gate-ok + outputs PNG glyph/charset not passing → fix font and retry
4 generate_cover.py --screenshot … --title … --out … cover PNG, then pass verify-glyphs.py exit 1 → proceed to composition prohibited
4/6 verify-glyphs.py <img> --quiet exit 0 (stdout only 1 line to save tokens) exit 1 → suspected tofu blocks → fix font
5 count-cjk.mjs --file <utf8.txt> Total character count 15~50 exit 1 → Rewrite the introduction and recount
6 generate_diagram.py --html … --out … Chart PNG, then pass verify-glyphs.py --quiet same as cover
6 build-detail-zip.mjs --readme <md> --resources <dir> --out <zip> Package + verify in one step exit 1 → Fix and repackage according to the output
8 check-gates.mjs --cover <png> --detail <zip> --strict --max-age 3600 --quiet exit 0 (stdout only 1 line to save tokens) exit 1 → Roll back and rerun the gate
8 publish-work.mjs <utf8-params.json> #status=201(only output workId/workUrl/reward) 409/other; on failure, output the complete response as-is

Marker file location: Linux /tmp/;Windows os.tmpdir()(%TEMP%)。

Pre-lock

  • hcloud + AK/SK: Required for Step 1. Not installed/not configured → troubleshooting#domain-id-resolution-issues。
  • git:Step 3;zip:Step 6(Linux yum install zip; on Windows use .NET ZipFile). On Windows, first-time see windows-setup.md。
  • Connectivity:api.mjs GET "/v1/gallery/announcements/current" --prefix open-api-guest, if connectivity is OK, continue.
  • Version check (best effort):node <skill>/scripts/check-version.mjs— the script automatically reads this file's frontmatter version: and requests the platform version API for comparison.status=ok/status=skip(non-2xx/parse failure) → continue, do not block;status=outdated → use the script's upgrade messageas-isinform the user andstop publishing(together with the platform announcement API, the two commands can be executed in parallel or serially combined to reduce tool round trips).

Core Workflow

Step 1: Select Work Directory & Resolve IAM Domain Info

  1. Inform the user(selecting a directory = consent): will create IAM self-delegation SELF_VERIFY to generate STS temporary credentials (900s); permanent AK/SK stay local and are not uploaded.
  2. Scan project root:node <skill>/scripts/scan-projects.mjs— automatically recurse **/README.md, check for indicator files, exclude skills//node_modules//dist/ etc., and scan the CodeArts sandbox directory. Each stdout line is #project <n> <path> <type>。
  3. List candidates, wait for user selection → workDir。
  4. Parse Domain ID:node <skill>/scripts/resolve-domain.mjs [--hcloud <exe>]— automatically hcloud configure set --region + IAM KeystoneListAuthDomains + extract domain_id。stdout #domain=<id> name=<name>. When hcloud is not in PATH, pass --hcloud. Credential priority: env → hcloud already configured → guide user (troubleshooting#2)。
  5. Generate STS:python <skill>/scripts/gen_sts.py --account <domainID> → sts-creds.json(includes _refresh, so that 401 automatically refreshes).
  6. Output:已获取 IAM Domain ID: <id>,用于将作品关联至您的华为云账号。

Output: workDir、domainID、credsFile。

Step 2: Run Project & Open Tunnel

Ask whether to run the project + open a tunnel. If declined, envUrl="" → Step 3。

  • Port cleanup:netstat -ano | findstr :<port>(Win), kill leftover processes.
  • Startup: prefer the entry script (npm run dev/python main.py); pure frontend npx http-server . -p <port>. ≤30s health check.
  • Verify content:curl -sf --max-time 3 http://localhost:<port> The first 100 characters must match this project (<title>/project name),Index of //404 → clear processes and restart.
  • Tunnel:devbridge host -p <port> -e 2,curl -sf --max-time 10 verification. Failure does not block; set envUrl="". See devbridge-tunnel.md。

Output: port、envUrl(or "")。

Step 3: Git Repository Info & Work Name

gitUrl required,gitBranch must be read explicitly.workName Parse/synthesize from README (<30 characters).

  1. git -C <workDir> remote get-url origin + branch --show-current。
  2. Credential troubleshooting:node <skill>/scripts/ensure-gitcode-credential.mjs— automatically detect local GitCode credentials (git credential fill/~/.git-credentials/$GITCODE_TOKEN/cmdkey). When there are no credentials, provide a feasible path by platform (on Linux, prompt manual configuration / on Windows, detect the gitcode-oauth skill and output the installation command). exit 0 = has credentials or an existing path; exit 1 = Windows has no credentials and the skill is not installed (stderr contains the installation command + Windows Git Bash compatibility hint).
  3. Credential stripping:gitUrl="$(node <skill>/scripts/strip-git-credential.mjs "$(git remote get-url origin)")". Hard validation: does not start with @、https:// ,.git end.
  4. Naming:node <skill>/scripts/extract-workname.mjs <workDir>— by priority frontmatter → H1 → manifest → index.html <title> → directory name extraction. stdout #name=<name> source=<来源>。source=dirname when the agent can synthesize/modify (<30 characters).

Output: gitUrl、gitBranch、workName。

Step 4: Cover Image

Gate (parallel):

Gate Command Marker
Render preflight.sh(Win: preflight.ps1) font-gate-ok
Encode ensure-utf8.mjs <dir> utf8-gate-ok

Gate failure prohibits screenshots/synthesis. preflight is based on the marker file ok=true (polling ≤180s).Linux first run must be backgrounded(downloading Chromium ~111MB; in the foreground it will be killed by the shell timeout SIGPIPE, and after the main process dies it will not write the gate file, making polling futile); Windows usually has the system browser preinstalled, so foreground is fine.

One-click cover generation (built-in: page count determination + single/multiple image probability sampling + screenshot + synthesis + validation):

node <skill>/scripts/build-cover.mjs \
  --url "http://127.0.0.1:<port>" --project-dir <workDir> \
  --title "<workName>" --tagline "<一句话>" --description "<主体介绍,1~3 句>" \
  --out <coverImagePath>
  • Layout decisions are closed-loop inside the script(agent-unaware): single-page projects use only 7 single-image layouts; multi-page projects (.html count ≥2) additionally include 3 multi-image layouts (large image + small image collage), sampled uniformly with equal probability from a unified probability pool; for multi-page projects the probability of multi-image appearing is 3/10.
  • Multi-image layouts capture thefirst page + candidate pages(up to 3 small images); if candidate page screenshots fail they are automatically skipped, with a minimum guarantee of 1 image.
  • stdout outputs only one line of result:#cover=… layout=… multi=yes|no pages=<n> scheme=…; logs go to stderr. Failure exits 1.

⚠️ workName↔cover strong dependency: the cover title is --title "${workName}"。Once renamed later due to 409, the cover must be re-synthesized with the new workName(see Step 8 rename and republish flow); publishing an old cover with a new name is prohibited.

For layout rules and visual baseline see work-preparation.md#screenshot-layout-rules。

Output: coverImagePath。

Step 5: Introduction

Read/write README to generate a one-sentence introduction.Total character count 15~50, continue only after the script count passes:

node <skill>/scripts/count-cjk.mjs --file "$env:TEMP\intro.txt"   # Win 必须 --file(GBK 转码问题)

For rules see work-preparation.md#introduction-generation。

⏩ Parallel:api.mjs GET "/v1/gallery/camps" --query "pageNo=1&pageSize=100&periodYear=${currentYear}" --creds-file "${credsFile}" --fields "id,name,school,status,startsAt,endsAt" prefetch for Step 7.

Output: introduction。

Step 6: Work Details

Generate a detailed article (500–1500 characters) with illustrations and package it into a zip.

  1. Diagrams: system architecture diagram required; optional 0–2 (routing/dependency/statistics diagrams). Use DevLens/GitNexus to understand the project before producing diagrams. Emoji are prohibited.
    python <skill>/scripts/generate_diagram.py --html diagram.html --out resources/<name>.png --width 1280
    python3 <skill>/scripts/verify-glyphs.py <img> --quiet   # 每张含中文图必跑
    
  2. Packaging zip + validation in one step(build-detail-zip.mjs built-in correct directory structure README.md@root + resources/; after packaging, automatically run server-side same-origin validation, cross-platform without needing zip/ZipFile):
    node <skill>/scripts/build-detail-zip.mjs --readme <README.md> --resources <dir> --out <workDetail.zip>
    

Output: detailsZipPath。

Step 7: Select Training Camp

  1. Get the training camp list (if prefetched in Step 5, use it directly).
  2. Based on startsAt/endsAt/status determine submission status (api-spec.md#submission-status-determination)。
  3. displayed in two tables: "can submit" / "cannot submit",each row must include the school(school) column;school when empty display —. Selecting a non-submittable item prompts "submission not open".

Output: trainingCampId。

Step 8: Publish

  1. Declare 开始发布作品 ${workName}。
  2. Gate recheck:node <skill>/scripts/check-gates.mjs --cover <png> --detail <zip> --strict --max-age 3600 --quiet(continue only on exit 0;publish-work.mjs built-in verifyGates() will also intercept).
  3. Parameters written to UTF-8 JSON, Idempotency-Key=gallery-publish-${domainID}-${timestamp}:
    node <skill>/scripts/publish-work.mjs <utf8-params.json> --max-age 3600
    # 成功仅输出 workId/workName/workUrl/reward;失败原样输出完整响应
    
  4. 201 → success, take workId/workUrl/reward, clean up temporary files.Points notice(regardless of success or failure, must prompt "only once per day"):
    • is_success===true:✅ 积分领取请求已提交。⚠️ 每日仅限一次。前往查看余额:https://developer.huaweicloud.com/grow
    • is_success===false:积分领取未成功:<error_msg> + daily once-only notice + growth center address + feedback entry https://gallery.developer.huaweicloud.com/gallery/profile?tab=feedback。
  5. 409 DUPLICATE → stop the current publish. Give options: ① abandon ② rename and republish.If renaming and republishing, must link:
    1. new name workName'(<30 characters): user-defined, or add a sequence number to the regular name without a version (e.g., 扫雷→扫雷-2). Arbitrarily concatenating unrelated characters is prohibited.
    2. Cover regeneration(the cover title must match the new name): use the original screenshot + original tagline/description, only replace --title "<workName'>" and recomposite:
      python <skill>/scripts/generate_cover.py --screenshot <原截图png> --title "<workName'>" --tagline "<原tagline>" --description "<原description>" --out <coverImagePath-新> --scheme auto
      python3 <skill>/scripts/verify-glyphs.py <coverImagePath-新> --quiet   # exit 0 才可继续
      
    3. Gate review (cover has been updated, must be rerun):node <skill>/scripts/check-gates.mjs --cover <封面-新> --detail <zip> --strict --max-age 3600 --quiet。
    4. Usenew workName' + newcover and new Idempotency-Key to republish (return to Step 3). Note: the detail zip usually does not need to be redone; only when the title or body text of the README inside the zip containsold work name(inconsistent with the new name) do you need to change the old name to the new name and repackage the detail zip.
  6. Other errors → inform <msg>(<code>), keep temporary files, and ask whether to modify and resend. For error codes, see error-codes.md。

References

Document Purpose When to read
troubleshooting.md Troubleshooting network/step failures Script error → check here first
error-codes.md Complete platform API error code table Consult the table when the API returns non-2xx
api-spec.md API contract, submission status determination Step 7/8 parse response
work-preparation.md Unified rules for naming/cover/description/details/charts For details in Steps 3–6, jump by table of contents
work-preparation-windows.md Windows-specific: PowerShell precheck/fonts/zip Windows only
work-preparation-linux.md Linux-specific: bash precheck/yum/fontconfig Linux only
windows-setup.md Windows first-time preparation: encoding/Playwright/zip Windows environment first time
self-verify-publish.md Self-delegation SELF_VERIFY and STS principles When Step 1 has problems
devbridge-tunnel.md DevBridge tunnel login/failure Step 2 tunnel anomaly
codearts-sandbox.md CodeArts sandbox directory Step 1 hits the sandbox