Not in the top 1,000 by GitHub stars

KevinGong2013/apkgo

一行命令,将 APK 发布到所有主流安卓应用商店

History

Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.

View weekly changes

SKILL.md

Week of Oct 26, 2026 · +0 / −0 lines

Before Network or broad shell → After Network or broad shell

9e8f87d67e48 → 9e8f87d67e48

Diff text is unavailable under the recorded licenses. Line counts and the GitHub link remain available.

Compare on GitHub

View on GitHubAdd to my skills

Verified commit 9e8f87d67e484b1b109a266240183efecb43936b

git clone --filter=blob:none --no-checkout https://github.com/KevinGong2013/apkgo.git .hotskills/kevingong2013-apkgo && git -C .hotskills/kevingong2013-apkgo checkout --detach 9e8f87d67e484b1b109a266240183efecb43936b # Copy each selected skill directory from .hotskills/kevingong2013-apkgo into .claude/skills/<skill-name>/
190GitHub stars
5stars in 7 days
1skill in this repository
24commits in 30 days

Heat

6.5
  • Star growth, last 7 daysNot available
  • Star growth, last 24 hoursNot available
  • Rank movement, last 7 daysNot available
  • Commits, last 30 daysNot available
  • Accounts asking about it through MCP, last 7 daysNot available
  • Hot votes this weekNot available

Heat never changes the order by stars, and sponsorship never touches it. How heat works

Stars over time

Oct 25, 2026Nov 6, 2026190

30-day change not yet available: not enough history.

Individual skills in this repository

How it works

apkgo

When your agent uses it

The apkgo-cloud CLI and distribution skill. Install the apkgo-cloud CLI (one-line installer, browser login, no local store secrets), then `preview` an APK to get a public 内测 download link (share it, anyone can install), `release` to distribute to Android app stores (Huawei, Xiaomi, OPPO, vivo, Honor, Meizu, Tencent, Google Play, Samsung, Pgyer, fir.im), the Apple App Store (.ipa) and HarmonyOS 鸿蒙 AppGallery (.app). Use this when the user wants to share a build or ship a release. To prepare store listing materials and create the app entries in each store before the first release, use the `apkgo-app-listing` skill. A REST Open API (X-API-Key, curl) is available as a fallback for CI/CD.

What it loads into context

Frontmatter

187 tokens

Always available to the agent

SKILL.md

4,508 tokens

When the skill is activated

Reference documents

38,968 tokens

Loaded on request

Token counts are estimates. Scripts run separately; they are not counted as reference context.

The playbook

  1. When to use
  2. Install & log in (CLI)
  3. Get a 内测 download link — `preview`
  4. Distribute to app stores — `release`
  5. Before the first release — hand off
  6. Supported stores
  7. CLI command reference
  8. Open API — CI/CD fallback
  9. Notes
  10. Agent 执行须知

Scripts executed separately

  • Dockerfile
  • cmd/audit.go
  • cmd/config.go
  • cmd/doctor.go
  • cmd/history.go
  • cmd/init.go
  • cmd/listing.go
  • cmd/root.go
  • cmd/stores.go
  • cmd/stores_test.go
  • cmd/telemetry-server/Dockerfile
  • cmd/telemetry-server/main.go
  • cmd/telemetry-server/main_test.go
  • cmd/upgrade.go
  • cmd/upload.go
  • cmd/upload_test.go
  • cmd/version.go
  • docs/install.sh
  • main.go
  • pkg/apk/apk.go
  • pkg/apk/apk_test.go
  • pkg/apk/at_test.go
  • pkg/apk/harmony.go
  • pkg/apk/harmony_test.go
  • pkg/apk/icon.go
  • pkg/apkgo/audit.go
  • pkg/apkgo/doctor.go
  • pkg/apkgo/doctor_test.go
  • pkg/apkgo/example_test.go
  • pkg/apkgo/job.go
  • pkg/apkgo/listing.go
  • pkg/apkgo/listing_fetch_test.go
  • pkg/apkgo/listing_test.go
  • pkg/apkgo/sandbox_test.go
  • pkg/config/config.go
  • pkg/config/source.go
  • pkg/config/source_test.go
  • pkg/ctxlog/ctxlog.go
  • pkg/history/history.go
  • pkg/hooks/hooks.go
  • pkg/httptrace/exchange.go
  • pkg/httptrace/file.go
  • pkg/httptrace/httptrace.go
  • pkg/httptrace/httptrace_test.go
  • pkg/httptrace/redact.go
  • pkg/httptrace/replay.go
  • pkg/httptrace/replay_test.go
  • pkg/httpx/fetch.go
  • pkg/httpx/multipart.go
  • pkg/httpx/multipart_test.go
  • pkg/httpx/offload.go
  • pkg/httpx/offload_test.go
  • pkg/imgcheck/imgcheck.go
  • pkg/imgcheck/imgcheck_test.go
  • pkg/internal/offloadtest/offloadtest.go
  • pkg/listing/listing.go
  • pkg/listing/listing_test.go
  • pkg/progress/progress.go
  • pkg/progress/progress_test.go
  • pkg/progress/resty_test.go
  • pkg/store/audit.go
  • pkg/store/audit_test.go
  • pkg/store/category.go
  • pkg/store/category_test.go
  • pkg/store/doctor.go
  • pkg/store/file.go
  • pkg/store/file_test.go
  • pkg/store/fir/fir.go
  • pkg/store/fir/fir_test.go
  • pkg/store/googleplay/googleplay.go
  • pkg/store/googleplay/googleplay_test.go
  • pkg/store/googleplay/listing.go
  • pkg/store/harmony/harmony.go
  • pkg/store/harmony/harmony_test.go
  • pkg/store/harmony/listing.go
  • pkg/store/harmony/listing_test.go
  • pkg/store/honor/honor.go
  • pkg/store/honor/honor_audit_test.go
  • pkg/store/honor/honor_listing_test.go
  • pkg/store/honor/honor_test.go
  • pkg/store/honor/listing_fetch.go
  • pkg/store/honor/listing_fetch_test.go
  • pkg/store/huawei/audit_test.go
  • pkg/store/huawei/byurl_test.go
  • pkg/store/huawei/huawei.go
  • pkg/store/huawei/listing.go
  • pkg/store/huawei/listing_fetch.go
  • pkg/store/huawei/listing_fetch_test.go
  • pkg/store/huawei/listing_test.go
  • pkg/store/huawei/replay_test.go
  • pkg/store/huawei/serviceaccount.go
  • pkg/store/listing.go
  • pkg/store/listing_conform.go
  • pkg/store/listing_conform_test.go
  • pkg/store/listing_fetch.go
  • pkg/store/listing_test.go
  • pkg/store/meizu/icon.go
  • pkg/store/meizu/icon_test.go
  • pkg/store/meizu/listing.go
  • pkg/store/meizu/listing_test.go
  • pkg/store/meizu/meizu.go
  • pkg/store/meizu/meizu_test.go
  • pkg/store/oppo/icon.go
  • pkg/store/oppo/icon_test.go
  • pkg/store/oppo/listing.go
  • pkg/store/oppo/listing_fetch.go
  • pkg/store/oppo/listing_fetch_test.go
  • pkg/store/oppo/listing_test.go
  • pkg/store/oppo/oppo.go
  • pkg/store/oppo/oppo_test.go
  • pkg/store/oppo/replay_test.go
  • pkg/store/pgyer/pgyer.go
  • pkg/store/pgyer/pgyer_test.go
  • pkg/store/registry.go
  • pkg/store/samsung/audit_test.go
  • pkg/store/samsung/auth_test.go
  • pkg/store/samsung/binary_test.go
  • pkg/store/samsung/listing_test.go
  • pkg/store/samsung/pem_test.go
  • pkg/store/samsung/samsung.go
  • pkg/store/samsung/version_test.go
  • pkg/store/scheduled_test.go
  • pkg/store/script/script.go
  • pkg/store/store.go
  • pkg/store/tencent/listing_fetch.go
  • pkg/store/tencent/listing_fetch_test.go
  • pkg/store/tencent/listing_test.go
  • pkg/store/tencent/tencent.go
  • pkg/store/tencent/tencent_test.go
  • pkg/store/vivo/listing_fetch.go
  • pkg/store/vivo/listing_fetch_test.go
  • pkg/store/vivo/listing_test.go
  • pkg/store/vivo/replay_test.go
  • pkg/store/vivo/trace_test.go
  • pkg/store/vivo/vivo.go
  • pkg/store/vivo/vivo_test.go
  • pkg/store/xiaomi/listing.go
  • pkg/store/xiaomi/listing_test.go
  • pkg/store/xiaomi/replay_test.go
  • pkg/store/xiaomi/xiaomi.go
  • pkg/store/xiaomi/xiaomi_test.go
  • pkg/telemetry/telemetry.go
  • pkg/telemetry/telemetry_test.go
  • pkg/update/check.go
  • pkg/uploader/events.go
  • pkg/uploader/events_test.go
  • pkg/uploader/manager.go
  • pkg/uploader/mpb_reporter.go
  • pkg/uploader/mpb_reporter_test.go
  • pkg/uploader/ndjson_reporter.go
  • pkg/uploader/ndjson_reporter_test.go
  • pkg/uploader/uploader.go
  • pkg/uploader/uploader_test.go

Files

  • .claude/skills/apkgo-cli-usage/SKILL.mddoc11,491 bytes
  • .github/workflows/ci.ymlasset439 bytes
  • .github/workflows/gitee-mirror.ymlasset1,908 bytes
  • .github/workflows/pages.ymlasset537 bytes
  • .github/workflows/release.ymlasset750 bytes
  • .github/workflows/telemetry-server.ymlasset747 bytes
  • .gitignoreasset302 bytes
  • .goreleaser.yamlasset1,139 bytes
  • CLAUDE.mddoc13,658 bytes
  • Dockerfileruns199 bytes
  • LICENSEasset4,714 bytes
  • README.en.mddoc38,405 bytes
  • README.mddoc25,423 bytes
  • SECURITY.mddoc4,280 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • SKILL.mdcore17,475 bytes
  • cmd/audit.goruns4,839 bytes
  • cmd/config.goruns4,470 bytes
  • cmd/doctor.goruns7,672 bytes
  • cmd/history.goruns1,752 bytes
  • cmd/init.goruns2,107 bytes
  • cmd/listing.goruns3,524 bytes
  • cmd/root.goruns4,604 bytes
  • cmd/stores.goruns2,549 bytes
  • cmd/stores_test.goruns801 bytes
  • cmd/telemetry-server/Dockerfileruns380 bytes
  • cmd/telemetry-server/docker-compose.ymlasset370 bytes
  • cmd/telemetry-server/main.goruns9,700 bytes
  • cmd/telemetry-server/main_test.goruns2,032 bytes
  • cmd/upgrade.goruns7,947 bytes
  • cmd/upload.goruns7,147 bytes
  • cmd/upload_test.goruns818 bytes
  • cmd/version.goruns579 bytes
  • docs/CNAMEasset13 bytes
  • docs/index.htmlasset22,632 bytes
  • docs/install.shruns2,550 bytes
  • docs/modu/privacy.htmlasset3,928 bytes
  • go.modasset749 bytes
  • go.sumasset3,403 bytes
  • main.goruns114 bytes
  • notes/app-info-update-research.mddoc30,495 bytes
  • notes/meizu-store-research.mddoc5,551 bytes
  • notes/phased-release-research.mddoc8,533 bytes
  • pkg/apk/apk.goruns4,990 bytes
  • pkg/apk/apk_test.goruns3,071 bytes
  • pkg/apk/at_test.goruns2,288 bytes
  • pkg/apk/harmony.goruns14,940 bytes
  • pkg/apk/harmony_test.goruns9,893 bytes
  • pkg/apk/icon.goruns2,225 bytes
  • pkg/apk/testdata/multilocale.apkasset3,719 bytes
  • pkg/apkgo/audit.goruns4,422 bytes
  • pkg/apkgo/doctor.goruns5,020 bytes
  • pkg/apkgo/doctor_test.goruns1,987 bytes
  • pkg/apkgo/example_test.goruns1,114 bytes
  • pkg/apkgo/job.goruns18,338 bytes
  • pkg/apkgo/listing.goruns13,687 bytes
  • pkg/apkgo/listing_fetch_test.goruns14,122 bytes
  • pkg/apkgo/listing_test.goruns4,206 bytes
  • pkg/apkgo/sandbox_test.goruns7,720 bytes
  • pkg/config/config.goruns8,567 bytes
  • pkg/config/source.goruns2,298 bytes
  • pkg/config/source_test.goruns1,660 bytes
  • pkg/ctxlog/ctxlog.goruns1,283 bytes
  • pkg/history/history.goruns1,998 bytes
  • pkg/hooks/hooks.goruns1,810 bytes
  • pkg/httptrace/exchange.goruns3,305 bytes
  • pkg/httptrace/file.goruns2,038 bytes
  • pkg/httptrace/httptrace.goruns13,622 bytes
  • pkg/httptrace/httptrace_test.goruns14,149 bytes
  • pkg/httptrace/redact.goruns5,574 bytes
  • pkg/httptrace/replay.goruns4,780 bytes
  • pkg/httptrace/replay_test.goruns4,234 bytes
  • pkg/httpx/fetch.goruns4,081 bytes
  • pkg/httpx/multipart.goruns7,009 bytes
  • pkg/httpx/multipart_test.goruns1,120 bytes
  • pkg/httpx/offload.goruns8,953 bytes
  • pkg/httpx/offload_test.goruns11,910 bytes
  • pkg/imgcheck/imgcheck.goruns1,516 bytes
  • pkg/imgcheck/imgcheck_test.goruns1,112 bytes
  • pkg/internal/offloadtest/offloadtest.goruns3,736 bytes
  • pkg/listing/listing.goruns5,327 bytes
  • pkg/listing/listing_test.goruns4,335 bytes
  • pkg/progress/progress.goruns3,073 bytes
  • pkg/progress/progress_test.goruns2,433 bytes
  • pkg/progress/resty_test.goruns2,450 bytes
  • pkg/store/CLAUDE.mddoc1,202 bytes
  • pkg/store/audit.goruns4,094 bytes
  • pkg/store/audit_test.goruns671 bytes
  • pkg/store/category.goruns7,172 bytes
  • pkg/store/category_test.goruns4,510 bytes
  • pkg/store/doctor.goruns2,693 bytes
  • pkg/store/file.goruns4,021 bytes
  • pkg/store/file_test.goruns2,455 bytes
  • pkg/store/fir/fir.goruns6,691 bytes
  • pkg/store/fir/fir_test.goruns2,488 bytes
  • pkg/store/googleplay/googleplay.goruns8,389 bytes
  • pkg/store/googleplay/googleplay_test.goruns14,287 bytes
  • pkg/store/googleplay/listing.goruns5,514 bytes
  • pkg/store/harmony/harmony.goruns24,709 bytes
  • pkg/store/harmony/harmony_test.goruns13,568 bytes
  • pkg/store/harmony/listing.goruns4,583 bytes
  • pkg/store/harmony/listing_test.goruns10,313 bytes
  • pkg/store/honor/honor.goruns35,829 bytes
  • pkg/store/honor/honor_audit_test.goruns3,840 bytes
  • pkg/store/honor/honor_listing_test.goruns16,080 bytes
  • pkg/store/honor/honor_test.goruns4,457 bytes
  • pkg/store/honor/listing_fetch.goruns1,814 bytes
  • pkg/store/honor/listing_fetch_test.goruns3,326 bytes
  • pkg/store/huawei/audit_test.goruns2,003 bytes
  • pkg/store/huawei/byurl_test.goruns8,264 bytes
  • pkg/store/huawei/huawei.goruns35,048 bytes
  • pkg/store/huawei/listing.goruns6,602 bytes
  • pkg/store/huawei/listing_fetch.goruns3,595 bytes
  • pkg/store/huawei/listing_fetch_test.goruns3,723 bytes
  • pkg/store/huawei/listing_test.goruns16,441 bytes
  • pkg/store/huawei/replay_test.goruns2,478 bytes
  • pkg/store/huawei/serviceaccount.goruns3,869 bytes
  • pkg/store/huawei/testdata/audit-withdrawn.trace.jsonlasset2,405 bytes
  • pkg/store/listing.goruns11,868 bytes
  • pkg/store/listing_conform.goruns3,141 bytes
  • pkg/store/listing_conform_test.goruns4,531 bytes
  • pkg/store/listing_fetch.goruns2,653 bytes
  • pkg/store/listing_test.goruns10,480 bytes
  • pkg/store/meizu/icon.goruns2,716 bytes
  • pkg/store/meizu/icon_test.goruns4,381 bytes
  • pkg/store/meizu/listing.goruns4,548 bytes
  • pkg/store/meizu/listing_test.goruns15,473 bytes
  • pkg/store/meizu/meizu.goruns20,905 bytes
  • pkg/store/meizu/meizu_test.goruns9,332 bytes
  • pkg/store/oppo/icon.goruns4,172 bytes
  • pkg/store/oppo/icon_test.goruns2,513 bytes
  • pkg/store/oppo/listing.goruns3,264 bytes
  • pkg/store/oppo/listing_fetch.goruns1,052 bytes
  • pkg/store/oppo/listing_fetch_test.goruns1,431 bytes
  • pkg/store/oppo/listing_test.goruns13,510 bytes
  • pkg/store/oppo/oppo.goruns31,538 bytes
  • pkg/store/oppo/oppo_test.goruns19,207 bytes
  • pkg/store/oppo/replay_test.goruns2,250 bytes
  • pkg/store/oppo/testdata/audit-withdrawn.trace.jsonlasset3,895 bytes
  • pkg/store/pgyer/pgyer.goruns8,209 bytes
  • pkg/store/pgyer/pgyer_test.goruns3,074 bytes
  • pkg/store/registry.goruns6,136 bytes
  • pkg/store/samsung/audit_test.goruns1,167 bytes
  • pkg/store/samsung/auth_test.goruns1,651 bytes
  • pkg/store/samsung/binary_test.goruns4,787 bytes
  • pkg/store/samsung/listing_test.goruns11,938 bytes
  • pkg/store/samsung/pem_test.goruns2,175 bytes
  • pkg/store/samsung/samsung.goruns30,174 bytes
  • pkg/store/samsung/version_test.goruns1,328 bytes
  • pkg/store/scheduled_test.goruns4,806 bytes
  • pkg/store/script/script.goruns2,048 bytes
  • pkg/store/store.goruns8,710 bytes
  • pkg/store/tencent/listing_fetch.goruns1,431 bytes
  • pkg/store/tencent/listing_fetch_test.goruns2,014 bytes
  • pkg/store/tencent/listing_test.goruns9,084 bytes
  • pkg/store/tencent/tencent.goruns25,693 bytes
  • pkg/store/tencent/tencent_test.goruns6,384 bytes
  • pkg/store/testdata/alpha-16x16.webpasset44 bytes
  • pkg/store/testdata/opaque-16x16.webpasset80 bytes
  • pkg/store/vivo/listing_fetch.goruns1,012 bytes
  • pkg/store/vivo/listing_fetch_test.goruns2,427 bytes
  • pkg/store/vivo/listing_test.goruns13,099 bytes
  • pkg/store/vivo/replay_test.goruns2,269 bytes
  • pkg/store/vivo/testdata/audit-withdrawn.trace.jsonlasset1,159 bytes
  • pkg/store/vivo/trace_test.goruns3,445 bytes
  • pkg/store/vivo/vivo.goruns28,316 bytes
  • pkg/store/vivo/vivo_test.goruns11,971 bytes
  • pkg/store/xiaomi/dev.api.public.cerasset997 bytes
  • pkg/store/xiaomi/listing.goruns2,958 bytes
  • pkg/store/xiaomi/listing_test.goruns14,300 bytes
  • pkg/store/xiaomi/replay_test.goruns1,695 bytes
  • pkg/store/xiaomi/testdata/audit-live.trace.jsonlasset670 bytes
  • pkg/store/xiaomi/testdata/helloworld.apkasset185,239 bytes
  • pkg/store/xiaomi/xiaomi.goruns20,783 bytes
  • pkg/store/xiaomi/xiaomi_test.goruns20,887 bytes
  • pkg/telemetry/telemetry.goruns2,335 bytes
  • pkg/telemetry/telemetry_test.goruns1,193 bytes
  • pkg/update/check.goruns3,077 bytes
  • pkg/uploader/events.goruns1,760 bytes
  • pkg/uploader/events_test.goruns2,525 bytes
  • pkg/uploader/manager.goruns2,236 bytes
  • pkg/uploader/mpb_reporter.goruns5,556 bytes
  • pkg/uploader/mpb_reporter_test.goruns1,795 bytes
  • pkg/uploader/ndjson_reporter.goruns4,942 bytes
  • pkg/uploader/ndjson_reporter_test.goruns1,217 bytes
  • pkg/uploader/uploader.goruns5,103 bytes
  • pkg/uploader/uploader_test.goruns1,836 bytes

No excerpt is shown for this license. Read the source on GitHub.

View the complete source on GitHub

Skills included

  • apkgo

Repository facts

License
No license detected
Created
Feb 18, 2023
Last pushed
Nov 5, 2026
Forks
31
Open issues
4
Project activity
Active

Before you install

Network or broad shell

Automated signals, not a guarantee

Checked Nov 6, 2026

Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.

Show 10 notes
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
Show all 862 signals by file

.claude/skills/apkgo-cli-usage/SKILL.md

  • Access to secretsline 18
    [Credential-related source omitted]
  • Access to secretsline 24
    [Credential-related source omitted]
  • Access to secretsline 35
    [Credential-related source omitted]
  • Access to secretsline 43
    [Credential-related source omitted]
  • Access to secretsline 48
    [Credential-related source omitted]
  • Access to secretsline 64
    [Credential-related source omitted]

.github/workflows/gitee-mirror.yml

  • Access to secretsline 38
    [Credential-related source omitted]
  • Network accessline 52
    git remote set-head origin -d           git push --force \             "https://oauth2:${GITEE_TOKEN}@gitee.com/${GITEE_OWNER}/${GITEE_REPO}.git" \
  • Network accessline 53
    git push --force \             "https://oauth2:${GITEE_TOKEN}@gitee.com/${GITEE_OWNER}/${GITEE_REPO}.git" \             'refs/remotes/origin/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
  • Network accessline 54
    [Credential-related source omitted]
  • Access to secretsline 54
    [Credential-related source omitted]

CLAUDE.md

  • Network accessline 8
    go install github.com/KevinGong2013/apkgo/v4@latest # or download binary from https://github.com/KevinGong2013/apkgo/releases
  • Network accessline 9
    # or download binary from https://github.com/KevinGong2013/apkgo/releases
  • Network accessline 178
    package properties only through `store.PackageFile` (`req.Package()`),   which takes a fact when given and reads the file otherwise. - `ctx = httpx.WithOffloader(ctx, o)`: every file-bearing request a store
  • Network accessline 179
    which takes a fact when given and reads the file otherwise. - `ctx = httpx.WithOffloader(ctx, o)`: every file-bearing request a store   makes (`httpx.DoMultipart`, `httpx.DoUpload`) is described to `o` as an
  • Network accessline 180
    - `ctx = httpx.WithOffloader(ctx, o)`: every file-bearing request a store
  • Access to secretsline 203
    [Credential-related source omitted]

Dockerfile

  • Executable scriptline 1
    Executable file

LICENSE

  • Network accessline 5
    <https://polyformproject.org/licenses/noncommercial/1.0.0>
  • Network accessline 40
    > Required Notice: Copyright Kevin Gong (https://github.com/KevinGong2013/apkgo)

README.en.md

  • Network accessline 3
    ![GitHub release](https://img.shields.io/github/v/release/KevinGong2013/apkgo) ![build](https://img.shields.io/github/actions/workflow/status/kevingong2013/apkgo/release.yml?style=flat-square) ![go](https://img.shields.io/github/go-mod/go-v
  • Network accessline 9
    > **Don't want to run CI or touch a terminal?** Try the hosted [**apkgo cloud**](https://apkgo.baici.tech) — release from a browser, with credentials stored server-side, multi-user collaboration, and full release history. No install, no ops
  • Dangerous shell operationline 16
    curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 16
    curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 39
    # macOS (Apple Silicon) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 40
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 42
    # macOS (Intel) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 43
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 45
    # Linux (x86_64) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 46
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 48
    # Linux (arm64) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 49
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 51
    # Windows (PowerShell) # Download apkgo_Windows_x86_64.zip from https://github.com/KevinGong2013/apkgo/releases/latest
  • Network accessline 52
    # Download apkgo_Windows_x86_64.zip from https://github.com/KevinGong2013/apkgo/releases/latest
  • Network accessline 97
    # Upload straight from an http(s) URL (fetched to a temp file; add headers for private URLs, repeatable) apkgo upload -f https://artifacts.example.com/app-v1.apk --store huawei apkgo upload -f https://private.example.com/app.apk --fetch-hea
  • Network accessline 98
    apkgo upload -f https://artifacts.example.com/app-v1.apk --store huawei
  • Network accessline 99
    [Credential-related source omitted]
  • Network accessline 117
    The vivo [sandbox environment](https://dev.vivo.com.cn/documentCenter/doc/327#s-l67kfh1m) has separate application data, `access_key`, and secrets from production. Follow the [online test environment instructions](https://dev.vivo.com.cn/do
  • Network accessline 143
    - Successful results list the submitted fields in `listing` (not for `already_done` results). pgyer and fir don't support listings — apkgo warns and uploads without it; `script` receives it as `Listing` in its stdin JSON. - To start from wh
  • Network accessline 144
    - To start from what the stores already have, `apkgo listing -p <package> --out ./listing` reads every store's current listing (read-only), saves the images under `./listing/assets` and writes `./listing/listing.yaml`, ready to edit and pas
  • Network accessline 145
    - Verification status: listing sync has been submitted end to end with real accounts on Huawei, Honor, OPPO, vivo, Xiaomi and Tencent. HarmonyOS, Meizu, Samsung and Google Play are implemented from the official docs but not yet verified aga
  • Access to secretsline 270
    [Credential-related source omitted]
  • Access to secretsline 280
    [Credential-related source omitted]
  • Access to secretsline 286
    [Credential-related source omitted]
  • Access to secretsline 305
    [Credential-related source omitted]
  • Network accessline 380
    [Credential-related source omitted]
  • Network accessline 381
    [Credential-related source omitted]
  • Network accessline 382
    [Credential-related source omitted]
  • Access to secretsline 395
    [Credential-related source omitted]
  • Access to secretsline 398
    [Credential-related source omitted]
  • Access to secretsline 399
    [Credential-related source omitted]
  • Access to secretsline 400
    [Credential-related source omitted]
  • Access to secretsline 402
    [Credential-related source omitted]
  • Access to secretsline 404
    [Credential-related source omitted]
  • Access to secretsline 408
    [Credential-related source omitted]
  • Access to secretsline 412
    [Credential-related source omitted]
  • Access to secretsline 413
    [Credential-related source omitted]
  • Network accessline 453
    [Credential-related source omitted]
  • Network accessline 454
    [Credential-related source omitted]
  • Network accessline 455
    [Credential-related source omitted]
  • Network accessline 456
    [Credential-related source omitted]
  • Network accessline 457
    [Credential-related source omitted]
  • Network accessline 458
    [Credential-related source omitted]
  • Network accessline 459
    [Credential-related source omitted]
  • Network accessline 460
    [Credential-related source omitted]
  • Network accessline 461
    [Credential-related source omitted]
  • Network accessline 462
    [Credential-related source omitted]
  • Network accessline 463
    [Credential-related source omitted]
  • Network accessline 464
    [Credential-related source omitted]
  • Network accessline 465
    [Credential-related source omitted]
  • Network accessline 466
    [Credential-related source omitted]
  • Network accessline 472
    [Credential-related source omitted]
  • Access to secretsline 483
    [Credential-related source omitted]
  • Network accessline 493
    [Credential-related source omitted]
  • Network accessline 513
    [Credential-related source omitted]
  • Access to secretsline 519
    [Credential-related source omitted]
  • Network accessline 530
    [Credential-related source omitted]
  • Network accessline 551
    [Credential-related source omitted]
  • Access to secretsline 557
    [Credential-related source omitted]
  • Network accessline 569
    [Credential-related source omitted]
  • Access to secretsline 575
    [Credential-related source omitted]
  • Network accessline 586
    [Credential-related source omitted]
  • Network accessline 609
    [Credential-related source omitted]
  • Access to secretsline 614
    [Credential-related source omitted]
  • Network accessline 623
    [Credential-related source omitted]
  • Network accessline 747
    [Credential-related source omitted]
  • Network accessline 748
    [Credential-related source omitted]
  • Access to secretsline 789
    [Credential-related source omitted]
  • Access to secretsline 807
    [Credential-related source omitted]
  • Access to secretsline 892
    [Credential-related source omitted]

README.md

  • Network accessline 3
    ![GitHub release](https://img.shields.io/github/v/release/KevinGong2013/apkgo) ![build](https://img.shields.io/github/actions/workflow/status/kevingong2013/apkgo/release.yml?style=flat-square) ![go](https://img.shields.io/github/go-mod/go-v
  • Network accessline 9
    > **不想搭 CI、不想碰命令行?** 试试托管版 [**apkgo cloud**](https://apkgo.baici.tech) —— 浏览器打开就能发版,凭证云端托管、多人协作、发布历史可追溯,免装免运维,运营和产品同事也能独立上手。除命令行版覆盖的安卓各大商店外,云端还支持 **iOS(App Store)** 与 **鸿蒙(HarmonyOS)** 上架,并可**实时监控应用审核 / 在架状态**。
  • Dangerous shell operationline 16
    curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 16
    curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 39
    # macOS (Apple Silicon) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 40
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 42
    # macOS (Intel) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 43
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Darwin_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 45
    # Linux (x86_64) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 46
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_x86_64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 48
    # Linux (arm64) curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 49
    curl -fsSL https://github.com/KevinGong2013/apkgo/releases/latest/download/apkgo_Linux_arm64.tar.gz | tar xz -C /usr/local/bin apkgo
  • Network accessline 51
    # Windows (PowerShell) # 从 https://github.com/KevinGong2013/apkgo/releases/latest 下载 apkgo_Windows_x86_64.zip
  • Network accessline 52
    # 从 https://github.com/KevinGong2013/apkgo/releases/latest 下载 apkgo_Windows_x86_64.zip
  • Network accessline 97
    [Credential-related source omitted]
  • Network accessline 98
    apkgo upload -f https://artifacts.example.com/app-v1.apk --store huawei
  • Network accessline 99
    [Credential-related source omitted]
  • Network accessline 139
    - 成功的结果里 `listing` 字段列出本次提交的资料项;版本已在商店侧(`already_done`)时不列。pgyer、fir 不支持资料,会给出警告并照常上传;`script` 商店在 stdin JSON 的 `Listing` 字段收到资料。 - 想从商店现有资料改起:`apkgo listing -p <包名> --out ./listing` 会把各商店当前的资料读下来(只读,不改动商店),图片存到 `./listing/assets`,并生成 `./li
  • Network accessline 140
    - 想从商店现有资料改起:`apkgo listing -p <包名> --out ./listing` 会把各商店当前的资料读下来(只读,不改动商店),图片存到 `./listing/assets`,并生成 `./listing/listing.yaml`,改完直接用于 `--listing`。每家商店的值各自写在 `stores` 下、不合并成默认值,所以读不到的商店不会出现在文件里,上传时保持原样。目前 OPPO、vivo、华为四项都能读回;商店返回的图片如果只是格式不
  • Network accessline 141
    - 验证情况:华为、荣耀、OPPO、vivo、小米、应用宝的资料同步已用真实账号走通提交;鸿蒙、魅族、三星、Google Play 按官方文档实现,尚未经真实账号验证,遇到问题请提 [issue](https://github.com/KevinGong2013/apkgo/issues)。
  • Network accessline 170
    vivo 的[沙箱环境](https://dev.vivo.com.cn/documentCenter/doc/327#s-l67kfh1m)与正式环境的应用数据、`access_key` 和密钥完全隔离;请按[在线测试环境说明](https://dev.vivo.com.cn/documentCenter/doc/327#s-b9qi52f4)先在沙箱创建应用并申请独立凭据。测试环境限制每个接口 100 次/天。
  • Access to secretsline 262
    [Credential-related source omitted]
  • Access to secretsline 272
    [Credential-related source omitted]
  • Access to secretsline 278
    [Credential-related source omitted]
  • Access to secretsline 297
    [Credential-related source omitted]
  • Network accessline 372
    [Credential-related source omitted]
  • Network accessline 373
    [Credential-related source omitted]
  • Network accessline 374
    [Credential-related source omitted]
  • Access to secretsline 387
    [Credential-related source omitted]
  • Access to secretsline 390
    [Credential-related source omitted]
  • Access to secretsline 391
    [Credential-related source omitted]
  • Access to secretsline 392
    [Credential-related source omitted]
  • Access to secretsline 394
    [Credential-related source omitted]
  • Access to secretsline 396
    [Credential-related source omitted]
  • Access to secretsline 400
    [Credential-related source omitted]
  • Access to secretsline 404
    [Credential-related source omitted]
  • Access to secretsline 405
    [Credential-related source omitted]
  • Access to secretsline 559
    [Credential-related source omitted]

SECURITY.md

  • Network accessline 21
    1. **GitHub Private Vulnerability Reporting** (preferred) —    <https://github.com/KevinGong2013/apkgo/security/advisories/new>
  • Network accessline 22
    <https://github.com/KevinGong2013/apkgo/security/advisories/new>
  • Network accessline 55
    - Vulnerabilities that require a malicious local config file (`apkgo.yaml`)   the user has authored — this is treated as trusted input. - The hosted `apkgo cloud` service (<https://apkgo.baici.tech>) — please
  • Network accessline 56
    the user has authored — this is treated as trusted input. - The hosted `apkgo cloud` service (<https://apkgo.baici.tech>) — please   contact that service directly.
  • Network accessline 57
    - The hosted `apkgo cloud` service (<https://apkgo.baici.tech>) — please
  • Network accessline 85
    1. **GitHub 私密漏洞报告**(推荐) ——    <https://github.com/KevinGong2013/apkgo/security/advisories/new>
  • Network accessline 86
    <https://github.com/KevinGong2013/apkgo/security/advisories/new>
  • Network accessline 116
    - 第三方应用商店 API 自身的漏洞(请联系对应厂商)。 - 依赖用户主动提供恶意本地配置文件(`apkgo.yaml`)才能触发的问题——本地配置文件视为可信输入。 - 托管版 `apkgo cloud`(<https://apkgo.baici.tech>)——请直接联系该服务。
  • Network accessline 118
    - 托管版 `apkgo cloud`(<https://apkgo.baici.tech>)——请直接联系该服务。

SKILL.md

  • Network accessline 7
    <!-- Canonical source: apkgo-cloud repo, web/public/skill.md — served at      https://apkgo.baici.tech/skill.md. The copy in the apkgo repo is a
  • Network accessline 8
    https://apkgo.baici.tech/skill.md. The copy in the apkgo repo is a
  • Network accessline 18
    Hosted at **`https://apkgo.baici.tech`**. Store credentials are encrypted server-side; multiple apps and team members per organization; async distribution with optional webhook callbacks; dashboard-visible audit log.
  • Dangerous shell operationline 34
    curl -fsSL https://apkgo.baici.tech/install.sh | sh   # installs the `apkgo-cloud` binary onto PATH
  • Network accessline 34
    curl -fsSL https://apkgo.baici.tech/install.sh | sh   # installs the `apkgo-cloud` binary onto PATH
  • Dangerous shell operationline 39
    Windows (PowerShell): `iwr https://apkgo.baici.tech/install.ps1 -UseBasicParsing | iex` — installs to `%LOCALAPPDATA%\apkgo-cloud` and adds it to your user PATH (open a new terminal afterwards). Full agent setup doc: **https://apkgo.baici.t
  • Network accessline 39
    Windows (PowerShell): `iwr https://apkgo.baici.tech/install.ps1 -UseBasicParsing | iex` — installs to `%LOCALAPPDATA%\apkgo-cloud` and adds it to your user PATH (open a new terminal afterwards). Full agent setup doc: **https://apkgo.baici.t
  • Network accessline 54
    The CLI parses the APK locally (package, version), uploads it directly to object storage, and prints a public link like `https://apkgo.baici.tech/d/AbC123...`. Send it to anyone — they get a download page and install the APK. Re-running `pr
  • Network accessline 74
    `release` only works for apps that already exist in each store. When the app has never been listed — the user says 「帮我上架」 for a new app, or needs icons, screenshots, copy, a privacy policy or to submit the store entry for review — switch to
  • Network accessline 103
    `APKGO_CLOUD_BASE` overrides the service URL (default `https://apkgo.baici.tech`).
  • Network accessline 112
    [Credential-related source omitted]
  • Network accessline 126
    KEY="apkgo_your_key"; BASE="https://apkgo.baici.tech/openapi/v1"; APK="app-release.apk"
  • Network accessline 128
    [Credential-related source omitted]
  • Network accessline 132
    [Credential-related source omitted]
  • Network accessline 141
    [Credential-related source omitted]
  • Network accessline 142
    -d "{\"object_key\":\"$OBJ\",\"package_name\":\"com.example.app\",\"version_name\":\"1.0.0\"}" \   $BASE/dist # → {"data":{"slug":"...","url":"https://apkgo.baici.tech/d/...","package_name":"..."}}
  • Network accessline 144
    # → {"data":{"slug":"...","url":"https://apkgo.baici.tech/d/...","package_name":"..."}}
  • Network accessline 152
    [Credential-related source omitted]
  • Network accessline 175
    [Credential-related source omitted]

cmd/audit.go

  • Executable scriptline 1
    Executable file

cmd/config.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 107
    [Credential-related source omitted]

cmd/doctor.go

  • Executable scriptline 1
    Executable file

cmd/history.go

  • Executable scriptline 1
    Executable file

cmd/init.go

  • Executable scriptline 1
    Executable file
  • Network accessline 43
    var b strings.Builder 		b.WriteString("# apkgo configuration\n") 		b.WriteString("# Docs: https://github.com/KevinGong2013/apkgo\n\n")
  • Network accessline 44
    b.WriteString("# apkgo configuration\n") 		b.WriteString("# Docs: https://github.com/KevinGong2013/apkgo\n\n") 		b.WriteString("stores:\n")
  • Network accessline 45
    b.WriteString("# Docs: https://github.com/KevinGong2013/apkgo\n\n")

cmd/listing.go

  • Executable scriptline 1
    Executable file

cmd/root.go

  • Executable scriptline 1
    Executable file

cmd/stores.go

  • Executable scriptline 1
    Executable file

cmd/stores_test.go

  • Executable scriptline 1
    Executable file

cmd/telemetry-server/Dockerfile

  • Executable scriptline 1
    Executable file

cmd/telemetry-server/main.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 238
    [Credential-related source omitted]

cmd/telemetry-server/main_test.go

  • Executable scriptline 1
    Executable file

cmd/upgrade.go

  • Executable scriptline 1
    Executable file
  • Network accessline 25
    const ( 	releaseAPI       = "https://api.github.com/repos/KevinGong2013/apkgo/releases/latest"
  • Network accessline 26
    releaseAPI       = "https://api.github.com/repos/KevinGong2013/apkgo/releases/latest"
  • Network accessline 27
    giteeReleaseAPI  = "https://gitee.com/api/v5/repos/ForTheDream/apkgo/releases/tags/" // append <tag>
  • Network accessline 28
    ghproxyURLPrefix = "https://ghproxy.com/"
  • Network accessline 116
    func fetchLatestRelease() (*ghRelease, error) { 	client := &http.Client{Timeout: 15 * time.Second}
  • Network accessline 117
    client := &http.Client{Timeout: 15 * time.Second}
  • Network accessline 198
    func resolveGiteeAssetURL(tag, assetName string) (string, error) { 	client := &http.Client{Timeout: 15 * time.Second}
  • Network accessline 199
    client := &http.Client{Timeout: 15 * time.Second}
  • Network accessline 225
    func downloadAndExtract(assetURL string) ([]byte, error) { 	client := &http.Client{Timeout: 5 * time.Minute}
  • Network accessline 226
    client := &http.Client{Timeout: 5 * time.Minute}

cmd/upload.go

  • Executable scriptline 1
    Executable file
  • Network accessline 79
    apkgo upload -f app.apk --notes-file CHANGELOG.md   apkgo upload -f app.apk --listing listing.yaml --dry-run   apkgo upload -f https://artifacts.example.com/app-v1.apk --store huawei
  • Network accessline 80
    [Credential-related source omitted]
  • Network accessline 81
    [Credential-related source omitted]
  • Network accessline 82
    [Credential-related source omitted]
  • Network accessline 83
    RunE: func(cmd *cobra.Command, args []string) error { 		fetchHeaders, err := httpx.ParseHeaders(flagFetchHeaders) 		if err != nil {
  • Network accessline 84
    fetchHeaders, err := httpx.ParseHeaders(flagFetchHeaders)

cmd/upload_test.go

  • Executable scriptline 1
    Executable file

cmd/version.go

  • Executable scriptline 1
    Executable file

docs/index.html

  • Network accessline 7
    <meta name="description" content="将 APK 一键发布到华为、小米、OPPO、vivo、荣耀、腾讯应用宝等主流安卓应用商店。为 CI/CD 和 AI Agent 设计。"> <style> @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700;800&family=Noto+Sans+SC:wght@400;500;6
  • Network accessline 9
    @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700;800&family=Noto+Sans+SC:wght@400;500;600;700&display=swap');
  • Network accessline 47
    content: '';   position: fixed; inset: 0;   background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stit
  • Network accessline 48
    position: fixed; inset: 0;   background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch
  • Network accessline 49
    background: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect wid
  • Network accessline 495
    <p class="tagline">一行命令,将 APK 发布到所有主流安卓应用商店</p>   <div class="hero-buttons">     <a href="https://github.com/KevinGong2013/apkgo" class="btn btn-primary">GitHub</a>
  • Network accessline 496
    <div class="hero-buttons">     <a href="https://github.com/KevinGong2013/apkgo" class="btn btn-primary">GitHub</a>     <a href="https://github.com/KevinGong2013/apkgo/releases" class="btn btn-ghost">Download</a>
  • Network accessline 497
    <a href="https://github.com/KevinGong2013/apkgo" class="btn btn-primary">GitHub</a>     <a href="https://github.com/KevinGong2013/apkgo/releases" class="btn btn-ghost">Download</a>     <a href="https://apkgo.baici.tech" class="btn btn-ghost
  • Network accessline 498
    <a href="https://github.com/KevinGong2013/apkgo/releases" class="btn btn-ghost">Download</a>
  • Network accessline 499
    <a href="https://apkgo.baici.tech" class="btn btn-ghost">Try Cloud →</a>
  • Network accessline 536
    </div>     <div class="cloud-action">       <a href="https://apkgo.baici.tech" class="btn btn-primary">立即试用 →</a>
  • Network accessline 537
    <div class="cloud-action">       <a href="https://apkgo.baici.tech" class="btn btn-primary">立即试用 →</a>       <span class="cloud-url">apkgo.baici.tech</span>
  • Network accessline 538
    <a href="https://apkgo.baici.tech" class="btn btn-primary">立即试用 →</a>
  • Network accessline 625
    &nbsp;&nbsp;&nbsp;&nbsp;{<br>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="t-key">"name"</span><span class="t-dim">:</span> <span class="t-str">"huawei"</span><span class="t-dim">,</span><br>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n
  • Network accessline 626
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="t-key">"name"</span><span class="t-dim">:</span> <span class="t-str">"huawei"</span><span class="t-dim">,</span><br>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="t-key">"console_url
  • Network accessline 627
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="t-key">"console_url"</span><span class="t-dim">:</span> <span class="t-str">"https://developer.huawei.com/..."</span><span class="t-dim">,</span><br>
  • Access to secretsline 630
    [Credential-related source omitted]
  • Network accessline 643
    <h2 class="section-title">安装</h2>     <div class="install-grid">       <div class="install-item"><span class="method">一键</span><code>curl -fsSL https://apkgo.com.cn/install.sh | sh</code></div>
  • Network accessline 644
    <div class="install-grid">       <div class="install-item"><span class="method">一键</span><code>curl -fsSL https://apkgo.com.cn/install.sh | sh</code></div>       <div class="install-item"><span class="method">Skill</span><code>npx skills ad
  • Dangerous shell operationline 645
    <div class="install-item"><span class="method">一键</span><code>curl -fsSL https://apkgo.com.cn/install.sh | sh</code></div>
  • Network accessline 645
    <div class="install-item"><span class="method">一键</span><code>curl -fsSL https://apkgo.com.cn/install.sh | sh</code></div>
  • Network accessline 647
    <div class="install-item"><span class="method">Go</span><code>go install github.com/KevinGong2013/apkgo/v4@latest</code></div>       <div class="install-item"><span class="method">Docker</span><code>docker pull ghcr.io/kevingong2013/apkgo:l
  • Network accessline 648
    <div class="install-item"><span class="method">Docker</span><code>docker pull ghcr.io/kevingong2013/apkgo:latest</code></div>       <div class="install-item"><span class="method">Binary</span><code><a href="https://github.com/KevinGong2013/
  • Network accessline 649
    <div class="install-item"><span class="method">Binary</span><code><a href="https://github.com/KevinGong2013/apkgo/releases">github.com/KevinGong2013/apkgo/releases</a></code></div>
  • Network accessline 654
    <footer>   Apache License 2.0 &middot; <a href="https://github.com/KevinGong2013/apkgo">KevinGong2013/apkgo</a>
  • Network accessline 655
    Apache License 2.0 &middot; <a href="https://github.com/KevinGong2013/apkgo">KevinGong2013/apkgo</a>

docs/install.sh

  • Executable scriptline 1
    #!/bin/sh
  • Network accessline 2
    # apkgo installer — https://apkgo.com.cn
  • Network accessline 3
    # # Usage: #   curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 4
    # Usage: #   curl -fsSL https://apkgo.com.cn/install.sh | sh #
  • Dangerous shell operationline 5
    #   curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 5
    #   curl -fsSL https://apkgo.com.cn/install.sh | sh
  • Network accessline 18
    Linux)  os=Linux ;;   *) echo "Error: unsupported OS '$(uname -s)'" >&2      echo "Windows: download from https://github.com/$REPO/releases/latest" >&2
  • Network accessline 19
    *) echo "Error: unsupported OS '$(uname -s)'" >&2      echo "Windows: download from https://github.com/$REPO/releases/latest" >&2      exit 1 ;;
  • Network accessline 20
    echo "Windows: download from https://github.com/$REPO/releases/latest" >&2
  • Network accessline 30
    asset="apkgo_${os}_${arch}.tar.gz" if [ "$VERSION" = "latest" ]; then   base="https://github.com/$REPO/releases/latest/download"
  • Network accessline 31
    if [ "$VERSION" = "latest" ]; then   base="https://github.com/$REPO/releases/latest/download" else
  • Network accessline 32
    base="https://github.com/$REPO/releases/latest/download"
  • Network accessline 33
    else   base="https://github.com/$REPO/releases/download/$VERSION" fi
  • Network accessline 34
    base="https://github.com/$REPO/releases/download/$VERSION"
  • Dangerous shell operationline 46
    trap 'rm -rf "$tmp"' EXIT
  • Network accessline 48
    echo "==> Downloading $asset" curl -fsSL "$base/$asset"        -o "$tmp/$asset"
  • Network accessline 49
    curl -fsSL "$base/$asset"        -o "$tmp/$asset"
  • Network accessline 50
    curl -fsSL "$base/checksums.txt" -o "$tmp/checksums.txt"
  • Network accessline 72
    echo "Error: $INSTALL_DIR is not writable." >&2   echo "  Try: APKGO_INSTALL_DIR=\"\$HOME/.local/bin\" sh install.sh" >&2   echo "  Or:  curl -fsSL https://apkgo.com.cn/install.sh | sudo sh" >&2
  • Network accessline 73
    echo "  Try: APKGO_INSTALL_DIR=\"\$HOME/.local/bin\" sh install.sh" >&2   echo "  Or:  curl -fsSL https://apkgo.com.cn/install.sh | sudo sh" >&2   exit 1
  • Dangerous shell operationline 74
    echo "  Or:  curl -fsSL https://apkgo.com.cn/install.sh | sudo sh" >&2
  • Network accessline 74
    echo "  Or:  curl -fsSL https://apkgo.com.cn/install.sh | sudo sh" >&2

docs/modu/privacy.html

  • Network accessline 24
    </ul> <h2>三、网络访问</h2> <p>本应用申请了网络权限,<strong>仅用于加载你打开的文档中引用的网络图片</strong>(例如 Markdown 中的 <code>![](https://…)</code>)。加载时,你的手机会直接向图片所在的服务器发起请求,该服务器可能会按其自身的规则记录请求信息(如 IP 地址)。本应用自身不会向我们的服务器发送任何数据。</p>
  • Network accessline 25
    <h2>三、网络访问</h2> <p>本应用申请了网络权限,<strong>仅用于加载你打开的文档中引用的网络图片</strong>(例如 Markdown 中的 <code>![](https://…)</code>)。加载时,你的手机会直接向图片所在的服务器发起请求,该服务器可能会按其自身的规则记录请求信息(如 IP 地址)。本应用自身不会向我们的服务器发送任何数据。</p> <p>文档中的网页链接只有在你点击后,才会交给系统浏览器打开。</p>
  • Network accessline 26
    <p>本应用申请了网络权限,<strong>仅用于加载你打开的文档中引用的网络图片</strong>(例如 Markdown 中的 <code>![](https://…)</code>)。加载时,你的手机会直接向图片所在的服务器发起请求,该服务器可能会按其自身的规则记录请求信息(如 IP 地址)。本应用自身不会向我们的服务器发送任何数据。</p>

main.go

  • Executable scriptline 1
    Executable file

notes/app-info-update-research.md

  • Network accessline 98
    [Credential-related source omitted]
  • Access to secretsline 98
    [Credential-related source omitted]
  • Network accessline 107
    - **基础信息**:另有 `update-app-info` 可改分类、官网、客服、隐私政策等。 - **生效方式**:所有改动走 `submit-audit` 审核通过后生效。 - 来源:https://developer.honor.com/cn/doc/guides/101359(SPA,正文 JSON:`https://developer.honor.com/document/portal/tree/101359?platformNo=10001&lang=cn` 
  • Network accessline 109
    - 来源:https://developer.honor.com/cn/doc/guides/101359(SPA,正文 JSON:`https://developer.honor.com/document/portal/tree/101359?platformNo=10001&lang=cn` → `data.documentInfo.text`)
  • Network accessline 113
    国内网关 `https://developer-api.vivo.com.cn/router/rest`(apkgo 已用同一套 access_key/access_secret HMAC-SHA256 签名),method 风格。
  • Network accessline 128
    - **apkgo 接入点**:`pkg/store/vivo/vivo.go` 的 `upload()`(构建 `updateReq` 处)和 `maybeURLPush()`;需要时先传 icon/截图拿流水号,再把字段追加进现有更新请求。`app.query.details` 返回 `icon`/`screenshot`/`detailDesc`/`simpleDesc` 可用于核对。 - **仍未确认**:`sync.update` 是否本身即进入审核(文档未写明;旁
  • Network accessline 130
    - 来源:国内文档中心 https://dev.vivo.com.cn/documentCenter/doc/343(sync.update.app)、517(sync.update.subpackage.app)、356(update.app)、519(update.subpackage.app)、329(upload.icon)、331(upload.screenshot)、346(查询详细信息)、344(字典)、326(传包介绍)、12(审核规范)。
  • Network accessline 134
    [Credential-related source omitted]
  • Access to secretsline 134
    [Credential-related source omitted]
  • Network accessline 157
    - **图片**:`/resource/v1/upload/get-upload-url` 拿上传地址 + 一次性 sign → multipart 上传(`type=photo`)拿 URL。 - **待实测**:审核中能否调 `updm`(文档未列状态前提);建议调用前查 `audit_status` / `update_info_check`,`update_info_check=1` 时跳过。 - 来源:官方文档 SPA,后端 `POST https://open.o
  • Network accessline 159
    - 来源:官方文档 SPA,后端 `POST https://open.oppomobile.com/oneoppoapi/doc/detail`(body `{"doc_id":N}`,无需登录);10999 发布版本、11000 更新资料、11002 多包资料更新、11003 文件上传、11004 应用详情(浏览器:`https://open.oppomobile.com/new/developmentDoc/info?id=11000`)。
  • Network accessline 163
    全部走 apkgo 已用的 `/dev/push`(`https://api.developer.xiaomi.com/devupload`),鉴权(email + private_key + cert)无需改动。
  • Network accessline 169
    - **生效方式**:编辑资料后与更新版本一样「提交审核 → 等待 1–3 个工作日」;**驳回状态下不能编辑资料**,只能走更新版本。 - **待实测**:`synchroType=1`(apkgo 现有路径)时传 desc/brief/截图是否生效(第三方 BioforestChain/android-auto-distribute 会一起传,但只证明接口接受);`synchroType=2` 不带 APK 能否调通。 - 来源:https://dev.mi.com/di
  • Network accessline 171
    - 来源:https://dev.mi.com/distribute/doc/details?pId=1134 、pId=1248(SPA,正文 JSON:`https://dev.mi.com/uiueapi/doc/getArticle?aId=1134`)
  • Network accessline 175
    `https://developer.meizu.com`,apkgo 已接入(`pkg/store/meizu`),鉴权同现有 clientId/clientSecret → accessToken + SHA-256 签名头。详见 `notes/meizu-store-research.md`。
  • Network accessline 182
    - **素材上传**:`POST /open/api/v1/app/image/upload`(multipart,只有 `file` 参数)返回 `value.destFileName`;只接受 JPG/PNG/JPEG(错误码 113007)。**icon/截图尺寸、大小、张数文档均未给出**,审核规范只要求图标与安装后一致、无拉伸/模糊/黑白边、截图不能带其他品牌手机外观。 - **apkgo 现状**:`appDetail.publishBody` 从 `app/de
  • Network accessline 184
    - 来源:`https://apiopen.flyme.cn/api/web/v1/doc-wiki/detail?id=333`(API 文档 v1.07,2026-01-05)、id=110 审核规范、id=14 应用发布与管理、id=27 常见问题。
  • Network accessline 188
    `https://devapi.samsungapps.com`,鉴权同现有 Bearer JWT + service_account_id + content_id 方案。
  • Network accessline 196
    - **screenshots[]**:`screenshotKey`(保留原图填 null,替换填新 fileKey)、`reuseYn`(更新截图时必填,true 沿用 / false 替换)、`screenshotPath`(仅响应);删除即从数组去掉该项。JPG/PNG,320–3840px,宽高比 ≤2:1,**4–8 张**(<4 报 3001;替换未带 key 报 4125)。 - **多语言**:`addLanguage[]` 每项 `languagecode
  • Network accessline 197
    - **多语言**:`addLanguage[]` 每项 `languagecode`(c 小写)、`appTitle`、`description` 必填,`newFeature` 可选,各带 `screenshots[]`。 - **图片上传**:`POST /seller/createUploadSessionId`(24h 有效)→ multipart `POST https://seller.samsungapps.com/galaxyapi/fileUpload`(
  • Network accessline 198
    - **图片上传**:`POST /seller/createUploadSessionId`(24h 有效)→ multipart `POST https://seller.samsungapps.com/galaxyapi/fileUpload`(`file` + `sessionId`)→ `fileKey`。
  • Network accessline 204
    `https://p.open.qq.com/open_file/developer_api`,共 4 个接口:`get_file_upload_info`、`update_app`、`query_app_detail`、`query_app_update_status`。
  • Network accessline 213
    - **图片**:`get_file_upload_info` 以 `file_type=img` 取流水号(每天最多 100 次)。 - 旧结论依据的「第三方运营指南只描述控制台操作」只说明控制台能改,不代表无 API。 - 来源:https://wikinew.open.qq.com/index.html#/iwiki/4015262492
  • Network accessline 215
    - 来源:https://wikinew.open.qq.com/index.html#/iwiki/4015262492
  • Network accessline 232
    | 商店 | 正文数据接口 | |---|---| | 华为 / 鸿蒙 | `POST https://svc-drcn.developer.huawei.com/community/servlet/consumer/cn/documentPortal/getDocumentById`,body `{"objectId":"<文档ID>","catalogName":"app","language":"cn"}` |
  • Network accessline 233
    |---|---| | 华为 / 鸿蒙 | `POST https://svc-drcn.developer.huawei.com/community/servlet/consumer/cn/documentPortal/getDocumentById`,body `{"objectId":"<文档ID>","catalogName":"app","language":"cn"}` | | 荣耀 | `GET https://developer.honor.com/docum
  • Network accessline 234
    | 华为 / 鸿蒙 | `POST https://svc-drcn.developer.huawei.com/community/servlet/consumer/cn/documentPortal/getDocumentById`,body `{"objectId":"<文档ID>","catalogName":"app","language":"cn"}` |
  • Network accessline 235
    | 荣耀 | `GET https://developer.honor.com/document/portal/tree/<id>?platformNo=10001&lang=cn` → `data.documentInfo.text` |
  • Network accessline 236
    | OPPO | `POST https://open.oppomobile.com/oneoppoapi/doc/detail`,body `{"doc_id":N}` |
  • Network accessline 237
    | 小米 | `GET https://dev.mi.com/uiueapi/doc/getArticle?aId=<pId>` |
  • Network accessline 238
    | vivo(国内) | `GET https://dev.vivo.com.cn/webapi/doc/info?id=<id>` → `data.content`(目录:`/webapi/doc/tree`) |
  • Network accessline 239
    | 魅族 | `GET https://apiopen.flyme.cn/api/web/v1/doc-wiki/detail?id=<id>`(目录:`.../doc-wiki/directory`) |

notes/meizu-store-research.md

  • Network accessline 3
    > 调研日期:2026-07-09(issue [#37](https://github.com/KevinGong2013/apkgo/issues/37))
  • Network accessline 62
    - 官方文档:https://open.flyme.cn/docs?id=333(正文数据接口:https://apiopen.flyme.cn/api/web/v1/doc-wiki/detail?id=333)
  • Network accessline 63
    - 实测:`GET https://developer.meizu.com/open/api/v1/token` → `{"code":113002,"message":"invalid param-clientId or clientSecret"}`

notes/phased-release-research.md

  • Network accessline 71
    - **查询**:`分阶段详情获取`(doc 884)。 - **指南**:分阶段发布能力使用指南(doc 666)。 - 走 `https://developer-api.vivo.com.cn/router/rest` 的统一签名网关(HMAC-SHA256),同上传接口。
  • Network accessline 73
    - 走 `https://developer-api.vivo.com.cn/router/rest` 的统一签名网关(HMAC-SHA256),同上传接口。

pkg/apk/apk.go

  • Executable scriptline 1
    Executable file

pkg/apk/apk_test.go

  • Executable scriptline 1
    Executable file

pkg/apk/at_test.go

  • Executable scriptline 1
    Executable file

pkg/apk/harmony.go

  • Executable scriptline 1
    Executable file

pkg/apk/harmony_test.go

  • Executable scriptline 1
    Executable file

pkg/apk/icon.go

  • Executable scriptline 1
    Executable file

pkg/apkgo/audit.go

  • Executable scriptline 1
    Executable file
  • Network accessline 81
    q := store.AuditQuery{Package: job.Package} 	if q.Package == "" && job.APKFile != "" { 		paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders)
  • Network accessline 82
    if q.Package == "" && job.APKFile != "" { 		paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders) 		if err != nil {
  • Network accessline 83
    paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders)

pkg/apkgo/doctor.go

  • Executable scriptline 1
    Executable file
  • Network accessline 90
    pkg := job.Package 	if pkg == "" && job.APKFile != "" { 		paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders)
  • Network accessline 91
    if pkg == "" && job.APKFile != "" { 		paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders) 		if err != nil {
  • Network accessline 92
    paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders)

pkg/apkgo/doctor_test.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 22
    [Credential-related source omitted]
  • Access to secretsline 47
    [Credential-related source omitted]
  • Access to secretsline 55
    [Credential-related source omitted]
  • Access to secretsline 69
    [Credential-related source omitted]

pkg/apkgo/example_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 28
    result, err := apkgo.Run(context.Background(), apkgo.Job{ 		APKFile: "https://artifacts.example.com/foo-v1.apk",
  • Network accessline 29
    APKFile: "https://artifacts.example.com/foo-v1.apk",

pkg/apkgo/job.go

  • Executable scriptline 1
    Executable file
  • Network accessline 6
    //	cfg, _ := config.Load("apkgo.yaml") // or build programmatically //	result, err := apkgo.Run(ctx, apkgo.Job{ //	    APKFile: "https://artifacts.example.com/v1.2.0.apk",
  • Network accessline 7
    //	result, err := apkgo.Run(ctx, apkgo.Job{ //	    APKFile: "https://artifacts.example.com/v1.2.0.apk", //	    Stores:  []string{"huawei", "tencent"},
  • Network accessline 8
    //	    APKFile: "https://artifacts.example.com/v1.2.0.apk",
  • Network accessline 187
    paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile, job.APKFile64}, job.FetchHeaders)
  • Network accessline 421
    var sourceURL, source64URL string 	if len(job.FetchHeaders) == 0 { 		if httpx.IsURL(job.APKFile) {
  • Network accessline 422
    if len(job.FetchHeaders) == 0 { 		if httpx.IsURL(job.APKFile) { 			sourceURL = job.APKFile
  • Network accessline 423
    if httpx.IsURL(job.APKFile) {
  • Network accessline 424
    sourceURL = job.APKFile 		} 		if httpx.IsURL(job.APKFile64) {
  • Network accessline 425
    } 		if httpx.IsURL(job.APKFile64) { 			source64URL = job.APKFile64
  • Network accessline 426
    if httpx.IsURL(job.APKFile64) {

pkg/apkgo/listing.go

  • Executable scriptline 1
    Executable file
  • Network accessline 109
    pkg := job.Package 	if pkg == "" && job.APKFile != "" { 		paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders)
  • Network accessline 110
    if pkg == "" && job.APKFile != "" { 		paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders) 		if err != nil {
  • Network accessline 111
    paths, cleanup, err := httpx.FetchToTempBatch(ctx, []string{job.APKFile}, job.FetchHeaders)
  • Network accessline 206
    return err 	} 	dl := &imageDownloader{dir: assets, bySHA: map[string]string{}, count: map[string]int{}, client: &http.Client{Timeout: 60 * time.Second}}
  • Network accessline 208
    dl := &imageDownloader{dir: assets, bySHA: map[string]string{}, count: map[string]int{}, client: &http.Client{Timeout: 60 * time.Second}}
  • Network accessline 238
    var problems []string 		if s.Icon != "" { 			name, from, err := dl.fetch(ctx, s.Icon, "icon", func(data []byte) ([]byte, bool) {
  • Network accessline 239
    if s.Icon != "" { 			name, from, err := dl.fetch(ctx, s.Icon, "icon", func(data []byte) ([]byte, bool) { 				return store.ConformListingImage(key, store.ListingIcon, data)
  • Network accessline 240
    name, from, err := dl.fetch(ctx, s.Icon, "icon", func(data []byte) ([]byte, bool) {
  • Network accessline 254
    var shots, converted []string 		for n, u := range s.Screenshots { 			name, from, err := dl.fetch(ctx, u, "screenshot", func(data []byte) ([]byte, bool) {
  • Network accessline 255
    for n, u := range s.Screenshots { 			name, from, err := dl.fetch(ctx, u, "screenshot", func(data []byte) ([]byte, bool) { 				return store.ConformListingImage(key, store.ListingScreenshots, data)
  • Network accessline 256
    name, from, err := dl.fetch(ctx, u, "screenshot", func(data []byte) ([]byte, bool) {
  • Network accessline 335
    bySHA  map[string]string // content sha256 → file name already written 	count  map[string]int    // kind → files written so far 	client *http.Client
  • Network accessline 336
    count  map[string]int    // kind → files written so far 	client *http.Client }
  • Network accessline 337
    client *http.Client
  • Network accessline 345
    func (d *imageDownloader) fetch(ctx context.Context, url, kind string, conform func([]byte) ([]byte, bool)) (name, from string, err error) {
  • Network accessline 353
    resp, err := d.client.Do(req) 	if err != nil { 		return "", "", httpx.RedactURLError(err)
  • Network accessline 354
    if err != nil { 		return "", "", httpx.RedactURLError(err) 	}
  • Network accessline 355
    return "", "", httpx.RedactURLError(err)

pkg/apkgo/listing_fetch_test.go

  • Executable scriptline 1
    Executable file

pkg/apkgo/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/apkgo/sandbox_test.go

  • Executable scriptline 1
    Executable file

pkg/config/config.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 145
    [Credential-related source omitted]

pkg/config/source.go

  • Executable scriptline 1
    Executable file

pkg/config/source_test.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 38
    [Credential-related source omitted]
  • Access to secretsline 47
    [Credential-related source omitted]
  • Access to secretsline 48
    [Credential-related source omitted]

pkg/ctxlog/ctxlog.go

  • Executable scriptline 1
    Executable file

pkg/history/history.go

  • Executable scriptline 1
    Executable file

pkg/hooks/hooks.go

  • Executable scriptline 1
    Executable file

pkg/httptrace/exchange.go

  • Executable scriptline 1
    Executable file

pkg/httptrace/file.go

  • Executable scriptline 1
    Executable file

pkg/httptrace/httptrace.go

  • Executable scriptline 1
    Executable file
  • Network accessline 197
    func (t *Tracer) Client(c *http.Client) *http.Client {
  • Network accessline 219
    func (t *Tracer) NewClient(timeout time.Duration) *http.Client {
  • Network accessline 221
    return nil 	} 	return t.Client(&http.Client{Timeout: timeout})
  • Network accessline 222
    } 	return t.Client(&http.Client{Timeout: timeout}) }
  • Network accessline 223
    return t.Client(&http.Client{Timeout: timeout})
  • Network accessline 307
    func Recorded(c *http.Client, req *http.Request, start time.Time, resp *http.Response, err error) *http.Response {

pkg/httptrace/httptrace_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 39
    func traced(t *testing.T) (*http.Client, *memRecorder) {
  • Network accessline 46
    t.Fatal("ForStore returned nil for a carried recorder") 	} 	return tr.Client(&http.Client{}), rec
  • Network accessline 47
    } 	return tr.Client(&http.Client{}), rec }
  • Network accessline 48
    return tr.Client(&http.Client{}), rec
  • Network accessline 51
    func do(t *testing.T, c *http.Client, req *http.Request) string {
  • Network accessline 71
    [Credential-related source omitted]
  • Network accessline 72
    [Credential-related source omitted]
  • Network accessline 73
    [Credential-related source omitted]
  • Access to secretsline 73
    [Credential-related source omitted]
  • Access to secretsline 78
    [Credential-related source omitted]
  • Access to secretsline 89
    [Credential-related source omitted]
  • Access to secretsline 115
    [Credential-related source omitted]
  • Access to secretsline 125
    [Credential-related source omitted]
  • Access to secretsline 126
    [Credential-related source omitted]
  • Access to secretsline 164
    [Credential-related source omitted]
  • Network accessline 170
    [Credential-related source omitted]
  • Access to secretsline 170
    [Credential-related source omitted]
  • Access to secretsline 193
    [Credential-related source omitted]
  • Access to secretsline 217
    [Credential-related source omitted]
  • Access to secretsline 234
    [Credential-related source omitted]
  • Access to secretsline 246
    [Credential-related source omitted]
  • Access to secretsline 268
    [Credential-related source omitted]
  • Network accessline 294
    c := &http.Client{}
  • Access to secretsline 347
    [Credential-related source omitted]
  • Network accessline 370
    t.Fatal(err) 	} 	rec.Record(Exchange{Store: "oppo", Method: "GET", URL: "https://x/a", Status: 200, Response: &Message{JSON: json.RawMessage(`{"a":1}`)}})
  • Network accessline 371
    } 	rec.Record(Exchange{Store: "oppo", Method: "GET", URL: "https://x/a", Status: 200, Response: &Message{JSON: json.RawMessage(`{"a":1}`)}}) 	rec.Record(Exchange{Store: "vivo", Method: "POST", URL: "https://x/b", Error: "dial tcp: refused"}
  • Network accessline 372
    rec.Record(Exchange{Store: "oppo", Method: "GET", URL: "https://x/a", Status: 200, Response: &Message{JSON: json.RawMessage(`{"a":1}`)}})
  • Network accessline 373
    rec.Record(Exchange{Store: "vivo", Method: "POST", URL: "https://x/b", Error: "dial tcp: refused"})
  • Network accessline 382
    rec, _ = NewFileRecorder(path) 	rec.Record(Exchange{Store: "oppo", Method: "GET", URL: "https://x/c"})
  • Network accessline 383
    rec.Record(Exchange{Store: "oppo", Method: "GET", URL: "https://x/c"})
  • Network accessline 388
    t.Fatal(err) 	} 	if len(got) != 3 || got[0].Seq != 1 || got[1].Seq != 2 || got[1].Error == "" || string(got[0].Response.JSON) != `{"a":1}` || got[2].URL != "https://x/c" {
  • Network accessline 389
    } 	if len(got) != 3 || got[0].Seq != 1 || got[1].Seq != 2 || got[1].Error == "" || string(got[0].Response.JSON) != `{"a":1}` || got[2].URL != "https://x/c" { 		t.Errorf("read back %+v", got)
  • Network accessline 390
    if len(got) != 3 || got[0].Seq != 1 || got[1].Seq != 2 || got[1].Error == "" || string(got[0].Response.JSON) != `{"a":1}` || got[2].URL != "https://x/c" {

pkg/httptrace/redact.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 20
    [Credential-related source omitted]

pkg/httptrace/replay.go

  • Executable scriptline 1
    Executable file

pkg/httptrace/replay_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 28
    flow := func(c *http.Client) (string, error) {
  • Network accessline 60
    rp := Replay(recorded).MatchQuery("method") 	last, err := flow(&http.Client{Transport: rp})
  • Network accessline 61
    last, err := flow(&http.Client{Transport: rp})
  • Network accessline 77
    req, _ := http.NewRequestWithContext(context.Background(), "POST", srv.URL+"/router/rest?method=task.status", strings.NewReader("{}")) 	if _, err := (&http.Client{Transport: rp}).Do(req); err == nil || !strings.Contains(err.Error(), "no rec
  • Network accessline 78
    if _, err := (&http.Client{Transport: rp}).Do(req); err == nil || !strings.Contains(err.Error(), "no recorded exchange") {
  • Network accessline 83
    func TestReplayMatchesAndRebuilds(t *testing.T) { 	rp := Replay([]Exchange{ 		{Method: "GET", URL: "https://api.store.test/app/info?pkg=a", Status: 200,
  • Network accessline 84
    rp := Replay([]Exchange{ 		{Method: "GET", URL: "https://api.store.test/app/info?pkg=a", Status: 200, 			Response: &Message{Headers: map[string]string{"Content-Type": "application/json", "Content-Length": "999"}, JSON: []byte(`{"v":1}`)}},
  • Network accessline 85
    {Method: "GET", URL: "https://api.store.test/app/info?pkg=a", Status: 200,
  • Network accessline 86
    Response: &Message{Headers: map[string]string{"Content-Type": "application/json", "Content-Length": "999"}, JSON: []byte(`{"v":1}`)}}, 		{Method: "POST", URL: "https://api.store.test/app/upd", Status: 403, Response: &Message{Text: "denied"}
  • Network accessline 87
    {Method: "POST", URL: "https://api.store.test/app/upd", Status: 403, Response: &Message{Text: "denied"}},
  • Network accessline 88
    {Method: "GET", URL: "https://api.store.test/down", Error: "dial tcp: i/o timeout"},
  • Network accessline 89
    }) 	c := &http.Client{Transport: rp} 	get := func(method, u string) (int, string, error) {
  • Network accessline 90
    c := &http.Client{Transport: rp}
  • Network accessline 103
    if code, body, err := get("POST", "https://api.store.test/app/upd"); err != nil || code != 403 || body != "denied" {
  • Network accessline 104
    t.Errorf("upd = %d %q %v", code, body, err) 	} 	if code, body, err := get("GET", "https://api.store.test/app/info?pkg=other"); err != nil || code != 200 || body != `{"v":1}` {
  • Network accessline 105
    } 	if code, body, err := get("GET", "https://api.store.test/app/info?pkg=other"); err != nil || code != 200 || body != `{"v":1}` { 		t.Errorf("info = %d %q %v", code, body, err)
  • Network accessline 106
    if code, body, err := get("GET", "https://api.store.test/app/info?pkg=other"); err != nil || code != 200 || body != `{"v":1}` {
  • Network accessline 107
    t.Errorf("info = %d %q %v", code, body, err) 	} 	if _, _, err := get("GET", "https://api.store.test/down"); err == nil || !strings.Contains(err.Error(), "i/o timeout") {
  • Network accessline 108
    } 	if _, _, err := get("GET", "https://api.store.test/down"); err == nil || !strings.Contains(err.Error(), "i/o timeout") { 		t.Errorf("recorded failure not replayed: %v", err)
  • Network accessline 109
    if _, _, err := get("GET", "https://api.store.test/down"); err == nil || !strings.Contains(err.Error(), "i/o timeout") {
  • Network accessline 110
    t.Errorf("recorded failure not replayed: %v", err) 	} 	for _, miss := range [][2]string{{"GET", "https://api.store.test/app/info"}, {"GET", "https://other.test/app/upd"}, {"PUT", "https://api.store.test/app/upd"}} {
  • Network accessline 111
    } 	for _, miss := range [][2]string{{"GET", "https://api.store.test/app/info"}, {"GET", "https://other.test/app/upd"}, {"PUT", "https://api.store.test/app/upd"}} { 		if _, _, err := get(miss[0], miss[1]); err == nil {
  • Network accessline 112
    for _, miss := range [][2]string{{"GET", "https://api.store.test/app/info"}, {"GET", "https://other.test/app/upd"}, {"PUT", "https://api.store.test/app/upd"}} {

pkg/httpx/fetch.go

  • Executable scriptline 1
    Executable file

pkg/httpx/multipart.go

  • Executable scriptline 1
    Executable file
  • Network accessline 65
    Progress progress.Reporter 	Client   *http.Client // optional; nil → default (30 min timeout)
  • Network accessline 66
    Client   *http.Client // optional; nil → default (30 min timeout)
  • Network accessline 71
    var defaultClient = &http.Client{Timeout: 30 * time.Minute}
  • Network accessline 187
    [Credential-related source omitted]
  • Network accessline 188
    [Credential-related source omitted]
  • Network accessline 189
    [Credential-related source omitted]

pkg/httpx/multipart_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 11
    [Credential-related source omitted]
  • Network accessline 12
    [Credential-related source omitted]
  • Network accessline 13
    [Credential-related source omitted]
  • Network accessline 19
    t.Errorf("query not redacted: %s", msg) 	} 	if !strings.Contains(msg, "https://bucket.cos.ap-guangzhou.myqcloud.com/apk/123.apk") {
  • Network accessline 20
    } 	if !strings.Contains(msg, "https://bucket.cos.ap-guangzhou.myqcloud.com/apk/123.apk") { 		t.Errorf("base URL lost: %s", msg)
  • Network accessline 21
    if !strings.Contains(msg, "https://bucket.cos.ap-guangzhou.myqcloud.com/apk/123.apk") {
  • Network accessline 31
    t.Error("plain error should be returned as-is") 	} 	noQuery := &url.Error{Op: "Post", URL: "https://api.example.com/upload", Err: errors.New("eof")}
  • Network accessline 32
    } 	noQuery := &url.Error{Op: "Post", URL: "https://api.example.com/upload", Err: errors.New("eof")} 	if got := RedactURLError(noQuery).(*url.Error).URL; got != "https://api.example.com/upload" {
  • Network accessline 33
    noQuery := &url.Error{Op: "Post", URL: "https://api.example.com/upload", Err: errors.New("eof")}
  • Network accessline 34
    if got := RedactURLError(noQuery).(*url.Error).URL; got != "https://api.example.com/upload" {

pkg/httpx/offload.go

  • Executable scriptline 1
    Executable file
  • Network accessline 142
    func send(ctx context.Context, client *http.Client, t *Transfer) (*http.Response, error) {
  • Network accessline 294
    Size     int64             // its size in bytes (required) 	Progress progress.Reporter // receives the bytes as they are sent 	Client   *http.Client      // nil → default (30 min timeout)
  • Network accessline 295
    Progress progress.Reporter // receives the bytes as they are sent 	Client   *http.Client      // nil → default (30 min timeout) }
  • Network accessline 296
    Client   *http.Client      // nil → default (30 min timeout)

pkg/httpx/offload_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 348
    }) 	_, err := DoUpload(WithOffloader(context.Background(), off), FileRequest{ 		Method: http.MethodPut, URL: "https://example.com/x", Path: "/remote/x", Size: 1,
  • Network accessline 349
    _, err := DoUpload(WithOffloader(context.Background(), off), FileRequest{ 		Method: http.MethodPut, URL: "https://example.com/x", Path: "/remote/x", Size: 1, 	})
  • Network accessline 350
    Method: http.MethodPut, URL: "https://example.com/x", Path: "/remote/x", Size: 1,

pkg/imgcheck/imgcheck.go

  • Executable scriptline 1
    Executable file

pkg/imgcheck/imgcheck_test.go

  • Executable scriptline 1
    Executable file

pkg/internal/offloadtest/offloadtest.go

  • Executable scriptline 1
    Executable file
  • Network accessline 55
    o.mu.Lock() 	defer o.mu.Unlock() 	return append([]*httpx.Transfer(nil), o.transfers...)
  • Network accessline 56
    defer o.mu.Unlock() 	return append([]*httpx.Transfer(nil), o.transfers...) }
  • Network accessline 57
    return append([]*httpx.Transfer(nil), o.transfers...)
  • Network accessline 86
    out.File64Path, out.File64Facts = remote(t, o, dir, "64", req.File64Path) 	} 	return &out, httpx.WithOffloader(ctx, o), o
  • Network accessline 87
    } 	return &out, httpx.WithOffloader(ctx, o), o }
  • Network accessline 88
    return &out, httpx.WithOffloader(ctx, o), o

pkg/listing/listing.go

  • Executable scriptline 1
    Executable file

pkg/listing/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/progress/progress.go

  • Executable scriptline 1
    Executable file

pkg/progress/progress_test.go

  • Executable scriptline 1
    Executable file

pkg/progress/resty_test.go

  • Executable scriptline 1
    Executable file

pkg/store/audit.go

  • Executable scriptline 1
    Executable file

pkg/store/audit_test.go

  • Executable scriptline 1
    Executable file

pkg/store/category.go

  • Executable scriptline 1
    Executable file

pkg/store/category_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 52
    }{ 		{"deadline exceeded", fmt.Errorf("upload to cos: %w", context.DeadlineExceeded), store.CategoryNetworkRetry}, 		{"url.Error", fmt.Errorf("upload: %w", &url.Error{Op: "Post", URL: "https://api.example.com/upload", Err: errors.New("use o
  • Network accessline 53
    {"deadline exceeded", fmt.Errorf("upload to cos: %w", context.DeadlineExceeded), store.CategoryNetworkRetry}, 		{"url.Error", fmt.Errorf("upload: %w", &url.Error{Op: "Post", URL: "https://api.example.com/upload", Err: errors.New("use of clo
  • Network accessline 54
    {"url.Error", fmt.Errorf("upload: %w", &url.Error{Op: "Post", URL: "https://api.example.com/upload", Err: errors.New("use of closed network connection")}), store.CategoryNetworkRetry},
  • Network accessline 109
    "rejected":     {errors.New("[invalid_client] bad secret"), store.CategoryAuthFailed}, 		"gateway 504":  {fmt.Errorf("auth: %w", store.StatusError("", 504, "timeout")), store.CategoryNetworkRetry}, 		"network drop": {fmt.Errorf("auth: %w", 
  • Network accessline 110
    "gateway 504":  {fmt.Errorf("auth: %w", store.StatusError("", 504, "timeout")), store.CategoryNetworkRetry}, 		"network drop": {fmt.Errorf("auth: %w", &url.Error{Op: "Get", URL: "https://x", Err: errors.New("connection reset by peer")}), st
  • Network accessline 111
    "network drop": {fmt.Errorf("auth: %w", &url.Error{Op: "Get", URL: "https://x", Err: errors.New("connection reset by peer")}), store.CategoryNetworkRetry},

pkg/store/doctor.go

  • Executable scriptline 1
    Executable file

pkg/store/file.go

  • Executable scriptline 1
    Executable file

pkg/store/file_test.go

  • Executable scriptline 1
    Executable file

pkg/store/fir/fir.go

  • Executable scriptline 1
    Executable file
  • Network accessline 22
    store.Register("fir", store.ConfigSchema{ 		Name:       "fir", 		ConsoleURL: "https://www.betaqr.com.cn/docs",
  • Network accessline 23
    Name:       "fir", 		ConsoleURL: "https://www.betaqr.com.cn/docs", 		Fields: []store.FieldSchema{
  • Network accessline 24
    ConsoleURL: "https://www.betaqr.com.cn/docs",
  • Network accessline 75
    type Store struct { 	client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 76
    client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default 	apiToken     string
  • Network accessline 77
    uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 89
    client := resty.New(). 		SetBaseURL("https://api.bq04.com")
  • Network accessline 90
    SetBaseURL("https://api.bq04.com")
  • Network accessline 157
    resp, err := httpx.DoMultipart(context.WithoutCancel(ctx), httpx.MultipartRequest{

pkg/store/fir/fir_test.go

  • Executable scriptline 1
    Executable file

pkg/store/googleplay/googleplay.go

  • Executable scriptline 1
    Executable file
  • Network accessline 29
    store.Register("googleplay", store.ConfigSchema{ 		Name:       "googleplay", 		ConsoleURL: "https://play.google.com/console",
  • Network accessline 30
    Name:       "googleplay", 		ConsoleURL: "https://play.google.com/console", 		AcceptsAAB: true,
  • Network accessline 31
    ConsoleURL: "https://play.google.com/console",
  • Network accessline 46
    const apiHost = "https://androidpublisher.googleapis.com"
  • Network accessline 169
    VersionCode int `json:"versionCode"` 	} 	httpResp, err := httpx.DoUpload(ctx, httpx.FileRequest{
  • Network accessline 170
    } 	httpResp, err := httpx.DoUpload(ctx, httpx.FileRequest{ 		Method: http.MethodPost,
  • Network accessline 171
    httpResp, err := httpx.DoUpload(ctx, httpx.FileRequest{
  • Network accessline 256
    claims := base64url(mustJSON(map[string]any{ 		"iss":   key.ClientEmail, 		"scope": "https://www.googleapis.com/auth/androidpublisher",
  • Network accessline 257
    "iss":   key.ClientEmail, 		"scope": "https://www.googleapis.com/auth/androidpublisher", 		"aud":   key.TokenURI,
  • Network accessline 258
    "scope": "https://www.googleapis.com/auth/androidpublisher",
  • Network accessline 273
    tokenURI := key.TokenURI 	if tokenURI == "" { 		tokenURI = "https://oauth2.googleapis.com/token"
  • Network accessline 274
    if tokenURI == "" { 		tokenURI = "https://oauth2.googleapis.com/token" 	}
  • Network accessline 275
    tokenURI = "https://oauth2.googleapis.com/token"
  • Access to secretsline 279
    [Credential-related source omitted]

pkg/store/googleplay/googleplay_test.go

  • Executable scriptline 1
    Executable file

pkg/store/googleplay/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/harmony/harmony.go

  • Executable scriptline 1
    Executable file
  • Network accessline 52
    const consoleURL = "https://developer.huawei.com/consumer/cn/service/josp/agc/index.html"
  • Network accessline 55
    store.Register(StoreName, store.ConfigSchema{ 		Name:                     StoreName, 		ConsoleURL:               "https://developer.huawei.com/consumer/cn/doc/app/agc-help-connect-api-obtain-server-auth-0000002271134661",
  • Network accessline 56
    Name:                     StoreName, 		ConsoleURL:               "https://developer.huawei.com/consumer/cn/doc/app/agc-help-connect-api-obtain-server-auth-0000002271134661", 		Platform:                 store.PlatformHarmony,
  • Network accessline 57
    ConsoleURL:               "https://developer.huawei.com/consumer/cn/doc/app/agc-help-connect-api-obtain-server-auth-0000002271134661",
  • Network accessline 74
    type Store struct { 	client         *resty.Client 	upload         *http.Client // raw PUT to the signed OBS URL
  • Network accessline 75
    client         *resty.Client 	upload         *http.Client // raw PUT to the signed OBS URL 	mode           huawei.AuthMode
  • Network accessline 76
    upload         *http.Client // raw PUT to the signed OBS URL
  • Network accessline 91
    return &Store{ 		client:         client, 		upload:         httptrace.ForStore(StoreName, cfg).Client(&http.Client{Timeout: 30 * time.Minute}),
  • Network accessline 92
    client:         client, 		upload:         httptrace.ForStore(StoreName, cfg).Client(&http.Client{Timeout: 30 * time.Minute}), 		mode:           mode,
  • Network accessline 93
    upload:         httptrace.ForStore(StoreName, cfg).Client(&http.Client{Timeout: 30 * time.Minute}),
  • Network accessline 281
    headers[http.CanonicalHeaderKey(k)] = v 	} 	resp, err := httpx.DoUpload(ctx, httpx.FileRequest{
  • Network accessline 282
    } 	resp, err := httpx.DoUpload(ctx, httpx.FileRequest{ 		Method:   method,
  • Network accessline 283
    resp, err := httpx.DoUpload(ctx, httpx.FileRequest{

pkg/store/harmony/harmony_test.go

  • Executable scriptline 1
    Executable file

pkg/store/harmony/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/harmony/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/honor/honor.go

  • Executable scriptline 1
    Executable file
  • Network accessline 26
    store.Register("honor", store.ConfigSchema{ 		Name:                     "honor", 		ConsoleURL:               "https://developer.honor.com/cn/doc/guides/101360",
  • Network accessline 27
    Name:                     "honor", 		ConsoleURL:               "https://developer.honor.com/cn/doc/guides/101360", 		SupportsScheduledRelease: true,
  • Network accessline 28
    ConsoleURL:               "https://developer.honor.com/cn/doc/guides/101360",
  • Access to secretsline 33
    [Credential-related source omitted]
  • Network accessline 218
    // Honor App Market publish API (rewritten 2026-04 to match current endpoints). // Reference: https://github.com/Xigong93/XiaoZhuan/tree/master/src/main/kotlin/com/xigong/xiaozhuan/channel/honor
  • Network accessline 219
    // Reference: https://github.com/Xigong93/XiaoZhuan/tree/master/src/main/kotlin/com/xigong/xiaozhuan/channel/honor
  • Network accessline 220
    // // Token host:    https://iam.developer.honor.com/auth/token // Publish host:  https://appmarket-openapi-drcn.cloud.honor.com/openapi/v1/publish
  • Network accessline 221
    // Token host:    https://iam.developer.honor.com/auth/token
  • Network accessline 222
    // Publish host:  https://appmarket-openapi-drcn.cloud.honor.com/openapi/v1/publish
  • Network accessline 224
    const ( 	tokenURL    = "https://iam.developer.honor.com/auth/token"
  • Network accessline 225
    tokenURL    = "https://iam.developer.honor.com/auth/token"
  • Network accessline 226
    publishBase = "https://appmarket-openapi-drcn.cloud.honor.com"
  • Network accessline 250
    type Store struct { 	client          *resty.Client // bound to publishBase with Bearer auth 	uploadClient    *http.Client  // streamed file uploads; nil = httpx's default
  • Network accessline 251
    client          *resty.Client // bound to publishBase with Bearer auth 	uploadClient    *http.Client  // streamed file uploads; nil = httpx's default 	accessToken     string        // kept separately so we can pass it on the signed upload U
  • Network accessline 252
    uploadClient    *http.Client  // streamed file uploads; nil = httpx's default
  • Access to secretsline 260
    [Credential-related source omitted]
  • Access to secretsline 262
    [Credential-related source omitted]
  • Access to secretsline 402
    [Credential-related source omitted]
  • Access to secretsline 419
    [Credential-related source omitted]
  • Access to secretsline 472
    [Credential-related source omitted]
  • Access to secretsline 477
    [Credential-related source omitted]
  • Network accessline 646
    rep.Phase("uploading") 	rep.Total(size) 	putHTTP, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 647
    rep.Total(size) 	putHTTP, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{ 		Method:   http.MethodPost,
  • Network accessline 648
    putHTTP, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 823
    if info.Intro == "" { 		return store.Categorize(store.CategoryConfigInvalid, 			fmt.Errorf("honor app intro (应用简介) is empty on the console — fill it in before publishing: https://developer.honor.com/cn/console"))
  • Network accessline 824
    return store.Categorize(store.CategoryConfigInvalid, 			fmt.Errorf("honor app intro (应用简介) is empty on the console — fill it in before publishing: https://developer.honor.com/cn/console")) 	}
  • Network accessline 825
    fmt.Errorf("honor app intro (应用简介) is empty on the console — fill it in before publishing: https://developer.honor.com/cn/console"))
  • Access to secretsline 949
    [Credential-related source omitted]

pkg/store/honor/honor_audit_test.go

  • Executable scriptline 1
    Executable file

pkg/store/honor/honor_listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/honor/honor_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 90
    t.Fatal(err) 	} 	const sourceURL = "https://cdn.example.com/app.apk"
  • Network accessline 91
    } 	const sourceURL = "https://cdn.example.com/app.apk" 	for _, minBytes := range []int64{0, 1} {
  • Network accessline 92
    const sourceURL = "https://cdn.example.com/app.apk"

pkg/store/honor/listing_fetch.go

  • Executable scriptline 1
    Executable file

pkg/store/honor/listing_fetch_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 38
    {"languageId":"zh-CN","appName":"应用","intro":"应用介绍","briefIntro":"一句话介绍"}], 		"fileInfo":[ 			{"fileName":"app.apk","fileType":100,"fileUrl":"https://f.test/app.apk"},
  • Network accessline 39
    "fileInfo":[ 			{"fileName":"app.apk","fileType":100,"fileUrl":"https://f.test/app.apk"}, 			{"fileName":"en.png","languageId":"en-US","fileType":1,"fileUrl":"https://f.test/icon-en.png"},
  • Network accessline 40
    {"fileName":"app.apk","fileType":100,"fileUrl":"https://f.test/app.apk"},
  • Network accessline 41
    {"fileName":"en.png","languageId":"en-US","fileType":1,"fileUrl":"https://f.test/icon-en.png"},
  • Network accessline 42
    {"fileName":"zh.png","languageId":"zh-CN","fileType":1,"fileUrl":"https://f.test/icon-zh.png"},
  • Network accessline 43
    {"fileName":"s2.png","languageId":"zh-CN","fileType":3,"fileUrl":"https://f.test/s2.png","order":1},
  • Network accessline 44
    {"fileName":"s1.png","languageId":"zh-CN","fileType":3,"fileUrl":"https://f.test/s1.png","order":0},
  • Network accessline 45
    {"fileName":"s3.png","languageId":"zh-CN","fileType":3,"fileUrl":"https://f.test/s3.png","order":2},
  • Network accessline 46
    {"fileName":"e1.png","languageId":"en-US","fileType":3,"fileUrl":"https://f.test/e1.png","order":0}]}}`)
  • Network accessline 50
    t.Fatalf("error: %s", got.Error) 	} 	if got.Store != "honor" || got.Brief != "一句话介绍" || got.Description != "应用介绍" || got.Icon != "https://f.test/icon-zh.png" {
  • Network accessline 51
    } 	if got.Store != "honor" || got.Brief != "一句话介绍" || got.Description != "应用介绍" || got.Icon != "https://f.test/icon-zh.png" { 		t.Errorf("listing = %+v", got)
  • Network accessline 52
    if got.Store != "honor" || got.Brief != "一句话介绍" || got.Description != "应用介绍" || got.Icon != "https://f.test/icon-zh.png" {
  • Network accessline 53
    t.Errorf("listing = %+v", got) 	} 	if want := []string{"https://f.test/s1.png", "https://f.test/s2.png", "https://f.test/s3.png"}; !reflect.DeepEqual(got.Screenshots, want) {
  • Network accessline 54
    } 	if want := []string{"https://f.test/s1.png", "https://f.test/s2.png", "https://f.test/s3.png"}; !reflect.DeepEqual(got.Screenshots, want) { 		t.Errorf("screenshots = %v, want %v", got.Screenshots, want)
  • Network accessline 55
    if want := []string{"https://f.test/s1.png", "https://f.test/s2.png", "https://f.test/s3.png"}; !reflect.DeepEqual(got.Screenshots, want) {
  • Network accessline 63
    "languageInfo":[{"languageId":"zh-CN","appName":"应用","intro":"应用介绍"}], 		"fileInfo":[ 			{"fileType":2,"fileUrl":"https://f.test/l1.png","languageId":"zh-CN","order":0},
  • Network accessline 64
    "fileInfo":[ 			{"fileType":2,"fileUrl":"https://f.test/l1.png","languageId":"zh-CN","order":0}, 			{"fileType":2,"fileUrl":"https://f.test/l2.png","languageId":"zh-CN","order":1}]}}`)
  • Network accessline 65
    {"fileType":2,"fileUrl":"https://f.test/l1.png","languageId":"zh-CN","order":0},
  • Network accessline 66
    {"fileType":2,"fileUrl":"https://f.test/l2.png","languageId":"zh-CN","order":1}]}}`)
  • Network accessline 68
    got := s.remoteListing("com.example.app") 	if got.Brief != "" || got.Icon != "" || len(got.Screenshots) != 2 || got.Screenshots[0] != "https://f.test/l1.png" {
  • Network accessline 69
    if got.Brief != "" || got.Icon != "" || len(got.Screenshots) != 2 || got.Screenshots[0] != "https://f.test/l1.png" {

pkg/store/huawei/audit_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 27
    // TestClassifyHuawei locks in the "app's packages exceeds the upper limit" // classification from https://github.com/KevinGong2013/apkgo/issues/31 —
  • Network accessline 28
    // classification from https://github.com/KevinGong2013/apkgo/issues/31 —

pkg/store/huawei/byurl_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 30
    name, url, pkg, want string 	}{ 		{"short name kept", "https://cdn.example.com/dl/app-release.apk", "com.example.app", "app-release.apk"},
  • Network accessline 31
    [Credential-related source omitted]
  • Network accessline 32
    {"short name kept", "https://cdn.example.com/dl/app-release.apk", "com.example.app", "app-release.apk"},
  • Network accessline 33
    [Credential-related source omitted]
  • Network accessline 34
    {"exactly 64 kept", "https://cdn.example.com/" + strings.Repeat("n", 60) + ".apk", "com.example.app", strings.Repeat("n", 60) + ".apk"},
  • Network accessline 35
    [Credential-related source omitted]
  • Network accessline 36
    {"suffix follows the link", "https://oss.example.com/apks/" + sha + ".aab", "com.example.app", "com.example.app.aab"}, 		{"no name in the link", "https://oss.example.com/", "com.example.app", "com.example.app.apk"}, 		{"no suffix in the lin
  • Network accessline 37
    {"no name in the link", "https://oss.example.com/", "com.example.app", "com.example.app.apk"}, 		{"no suffix in the link", "https://oss.example.com/download", "com.example.app", "com.example.app.apk"}, 		{"long name and long package: tail o
  • Network accessline 38
    {"no suffix in the link", "https://oss.example.com/download", "com.example.app", "com.example.app.apk"},
  • Network accessline 39
    {"long name and long package: tail of the name", "https://oss.example.com/" + sha + "-release.apk", longPkg, (sha + "-release")[len(sha+"-release")-60:] + ".apk"},
  • Network accessline 110
    [Credential-related source omitted]

pkg/store/huawei/huawei.go

  • Executable scriptline 1
    Executable file
  • Network accessline 23
    store.Register("huawei", store.ConfigSchema{ 		Name:                     "huawei", 		ConsoleURL:               "https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agcapi-getstarted-0000001111845114#section1785535363715",
  • Network accessline 24
    Name:                     "huawei", 		ConsoleURL:               "https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agcapi-getstarted-0000001111845114#section1785535363715", 		SupportsScheduledRelease: true,
  • Network accessline 25
    ConsoleURL:               "https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-Guides/agcapi-getstarted-0000001111845114#section1785535363715",
  • Network accessline 162
    const APIBase = "https://connect-api.cloud.huawei.com"
  • Access to secretsline 171
    [Credential-related source omitted]
  • Access to secretsline 176
    [Credential-related source omitted]
  • Access to secretsline 183
    [Credential-related source omitted]
  • Access to secretsline 218
    [Credential-related source omitted]
  • Network accessline 222
    type Store struct { 	client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 223
    client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default 	clientID     string       // for client_credentials mode; empty under service_account
  • Network accessline 224
    uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Access to secretsline 336
    [Credential-related source omitted]
  • Access to secretsline 345
    [Credential-related source omitted]
  • Network accessline 519
    } 	rep.Total(fSize) 	resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 520
    rep.Total(fSize) 	resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{ 		Method: http.MethodPost,
  • Network accessline 521
    resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 744
    const hwConsoleURL = "https://developer.huawei.com/consumer/cn/console"

pkg/store/huawei/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/huawei/listing_fetch.go

  • Executable scriptline 1
    Executable file

pkg/store/huawei/listing_fetch_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 32
    "appInfo":{"defaultLang":"zh-CN","releaseState":0}, 		"languages":[ 			{"lang":"en-US","appName":"App","appDesc":"English description","briefInfo":"English brief","icon":"https://img.test/en.png"},
  • Network accessline 33
    "languages":[ 			{"lang":"en-US","appName":"App","appDesc":"English description","briefInfo":"English brief","icon":"https://img.test/en.png"}, 			{"lang":"zh-CN","appName":"应用","appDesc":"应用介绍","briefInfo":"一句话简介",
  • Network accessline 34
    {"lang":"en-US","appName":"App","appDesc":"English description","briefInfo":"English brief","icon":"https://img.test/en.png"},
  • Network accessline 35
    {"lang":"zh-CN","appName":"应用","appDesc":"应用介绍","briefInfo":"一句话简介", 			 "icon":"https://img.test/lang-icon.png","introPic":"https://img.test/old1.png,https://img.test/old2.png", 			 "deviceMaterials":[
  • Network accessline 36
    "icon":"https://img.test/lang-icon.png","introPic":"https://img.test/old1.png,https://img.test/old2.png",
  • Network accessline 37
    "deviceMaterials":[ 				{"deviceType":5,"appIcon":"https://img.test/pad.png","screenShots":["https://img.test/pad1.png"]}, 				{"deviceType":4,"appIcon":"https://img.test/phone.png","screenShots":["https://img.test/p1.png","https://img.test
  • Network accessline 38
    {"deviceType":5,"appIcon":"https://img.test/pad.png","screenShots":["https://img.test/pad1.png"]},
  • Network accessline 39
    {"deviceType":4,"appIcon":"https://img.test/phone.png","screenShots":["https://img.test/p1.png","https://img.test/p2.png","https://img.test/p3.png"]}]}]}`)
  • Network accessline 43
    t.Fatalf("error: %s", got.Error) 	} 	if got.Store != "huawei" || got.Brief != "一句话简介" || got.Description != "应用介绍" || got.Icon != "https://img.test/phone.png" {
  • Network accessline 44
    } 	if got.Store != "huawei" || got.Brief != "一句话简介" || got.Description != "应用介绍" || got.Icon != "https://img.test/phone.png" { 		t.Errorf("listing = %+v", got)
  • Network accessline 45
    if got.Store != "huawei" || got.Brief != "一句话简介" || got.Description != "应用介绍" || got.Icon != "https://img.test/phone.png" {
  • Network accessline 46
    t.Errorf("listing = %+v", got) 	} 	if want := []string{"https://img.test/p1.png", "https://img.test/p2.png", "https://img.test/p3.png"}; !reflect.DeepEqual(got.Screenshots, want) {
  • Network accessline 47
    } 	if want := []string{"https://img.test/p1.png", "https://img.test/p2.png", "https://img.test/p3.png"}; !reflect.DeepEqual(got.Screenshots, want) { 		t.Errorf("screenshots = %v, want %v", got.Screenshots, want)
  • Network accessline 48
    if want := []string{"https://img.test/p1.png", "https://img.test/p2.png", "https://img.test/p3.png"}; !reflect.DeepEqual(got.Screenshots, want) {
  • Network accessline 57
    "languages":[ 			{"lang":"en-US","appDesc":"English description"}, 			{"lang":"zh-CN","appDesc":"应用介绍","icon":"https://img.test/icon.png",
  • Network accessline 58
    {"lang":"en-US","appDesc":"English description"}, 			{"lang":"zh-CN","appDesc":"应用介绍","icon":"https://img.test/icon.png", 			 "introPic":"https://img.test/1.png,https://img.test/2.png","deviceMaterials":"unexpected"}]}`)
  • Network accessline 59
    {"lang":"zh-CN","appDesc":"应用介绍","icon":"https://img.test/icon.png",
  • Network accessline 60
    "introPic":"https://img.test/1.png,https://img.test/2.png","deviceMaterials":"unexpected"}]}`)
  • Network accessline 61
    got := s.remoteListing(context.Background(), "com.example.app") 	if got.Error != "" || got.Description != "应用介绍" || got.Icon != "https://img.test/icon.png" || len(got.Screenshots) != 2 { 		t.Errorf("zh-CN fallback = %+v", got)
  • Network accessline 62
    if got.Error != "" || got.Description != "应用介绍" || got.Icon != "https://img.test/icon.png" || len(got.Screenshots) != 2 {

pkg/store/huawei/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/huawei/replay_test.go

  • Executable scriptline 1
    Executable file

pkg/store/huawei/serviceaccount.go

  • Executable scriptline 1
    Executable file
  • Network accessline 66
    sa.TokenURI = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"

pkg/store/huawei/testdata/audit-withdrawn.trace.jsonl

  • Network accessline 1
    {"seq":1,"time":"2026-01-01T00:00:00Z","store":"huawei","method":"GET","url":"https://connect-api.cloud.huawei.com/api/publish/v2/appid-list?packageName=com.example.app&packageTypes=1","request":{"headers":{"Content-Type":"application/json"
  • Network accessline 2
    {"seq":2,"time":"2026-01-01T00:00:00Z","store":"huawei","method":"GET","url":"https://connect-api.cloud.huawei.com/api/publish/v2/app-info?appId=100000000&releaseType=1","request":{"headers":{"Content-Type":"application/json"}},"status":200

pkg/store/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/listing_conform.go

  • Executable scriptline 1
    Executable file

pkg/store/listing_conform_test.go

  • Executable scriptline 1
    Executable file

pkg/store/listing_fetch.go

  • Executable scriptline 1
    Executable file

pkg/store/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/meizu/icon.go

  • Executable scriptline 1
    Executable file

pkg/store/meizu/icon_test.go

  • Executable scriptline 1
    Executable file

pkg/store/meizu/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/meizu/listing_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 42
    "category2Id": 12, "tagId": 34, "icon": "old/icon.png", 	"screenShots": ["old/s1.png", "old/s2.png"], "certificates": "c1.png,c2.png", 	"ageBracket": 3, "privacyPolicyUrl": "https://example.com/privacy",
  • Network accessline 43
    "screenShots": ["old/s1.png", "old/s2.png"], "certificates": "c1.png,c2.png", 	"ageBracket": 3, "privacyPolicyUrl": "https://example.com/privacy", 	"softwareAuthorNum": "2020SR000001", "qualifcation": "q", "dwmc": "Org",
  • Network accessline 44
    "ageBracket": 3, "privacyPolicyUrl": "https://example.com/privacy",
  • Network accessline 56
    "packageUrl": "apk/app.apk", "icon": "old/icon.png", 	"screenShots": ["old/s1.png", "old/s2.png"], "certificates": ["c1.png", "c2.png"], 	"privacyPolicyUrl": "https://example.com/privacy", "keyword": "a b",
  • Network accessline 57
    "screenShots": ["old/s1.png", "old/s2.png"], "certificates": ["c1.png", "c2.png"], 	"privacyPolicyUrl": "https://example.com/privacy", "keyword": "a b", 	"recommendDesc": "old brief", "softwareAuthorNum": "2020SR000001",
  • Network accessline 58
    "privacyPolicyUrl": "https://example.com/privacy", "keyword": "a b",

pkg/store/meizu/meizu.go

  • Executable scriptline 1
    Executable file
  • Network accessline 29
    const defaultBaseURL = "https://developer.meizu.com"
  • Network accessline 39
    store.Register("meizu", store.ConfigSchema{ 		Name:       "meizu", 		ConsoleURL: "https://open.flyme.cn",
  • Network accessline 40
    Name:       "meizu", 		ConsoleURL: "https://open.flyme.cn", 		Fields: []store.FieldSchema{
  • Network accessline 41
    ConsoleURL: "https://open.flyme.cn",
  • Access to secretsline 44
    [Credential-related source omitted]
  • Network accessline 93
    baseURL      string // defaultBaseURL; overridden by tests 	client       *resty.Client 	uploadClient *http.Client // multipart uploads; shares the relaxed-handshake transport
  • Network accessline 94
    client       *resty.Client 	uploadClient *http.Client // multipart uploads; shares the relaxed-handshake transport 	clientID     string
  • Network accessline 95
    uploadClient *http.Client // multipart uploads; shares the relaxed-handshake transport
  • Access to secretsline 103
    [Credential-related source omitted]
  • Access to secretsline 105
    [Credential-related source omitted]
  • Network accessline 115
    baseURL:      defaultBaseURL, 		client:       resty.New().SetBaseURL(defaultBaseURL).SetTransport(transport), 		uploadClient: &http.Client{Timeout: 30 * time.Minute, Transport: transport},
  • Network accessline 116
    client:       resty.New().SetBaseURL(defaultBaseURL).SetTransport(transport), 		uploadClient: &http.Client{Timeout: 30 * time.Minute, Transport: transport}, 		clientID:     clientID,
  • Network accessline 117
    uploadClient: &http.Client{Timeout: 30 * time.Minute, Transport: transport},
  • Network accessline 373
    resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{

pkg/store/meizu/meizu_test.go

  • Executable scriptline 1
    Executable file

pkg/store/oppo/icon.go

  • Executable scriptline 1
    Executable file

pkg/store/oppo/icon_test.go

  • Executable scriptline 1
    Executable file

pkg/store/oppo/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/oppo/listing_fetch.go

  • Executable scriptline 1
    Executable file

pkg/store/oppo/listing_fetch_test.go

  • Executable scriptline 1
    Executable file

pkg/store/oppo/listing_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 26
    oldSummary = "旧的一句话简介" 	oldDesc    = "这是商店里现有的软件介绍内容足够二十个字了吧" 	oldPicURL  = "https://cdn.test/old1.png,https://cdn.test/old2.png"
  • Network accessline 27
    oldDesc    = "这是商店里现有的软件介绍内容足够二十个字了吧" 	oldPicURL  = "https://cdn.test/old1.png,https://cdn.test/old2.png" )
  • Network accessline 28
    oldPicURL  = "https://cdn.test/old1.png,https://cdn.test/old2.png"
  • Access to secretsline 98
    [Credential-related source omitted]
  • Access to secretsline 110
    [Credential-related source omitted]
  • Network accessline 168
    } 			writeJSON(w, map[string]any{"errno": 0, "data": map[string]any{ 				"url": "https://cdn.test/" + hdr.Filename, "md5": "md5", "id": "1",
  • Network accessline 169
    writeJSON(w, map[string]any{"errno": 0, "data": map[string]any{ 				"url": "https://cdn.test/" + hdr.Filename, "md5": "md5", "id": "1", 			}})
  • Network accessline 170
    "url": "https://cdn.test/" + hdr.Filename, "md5": "md5", "id": "1",
  • Network accessline 307
    }, 			summary: "新版一句话简介", desc: newDesc, 			iconURL: "https://cdn.test/icon.png",
  • Network accessline 308
    summary: "新版一句话简介", desc: newDesc, 			iconURL: "https://cdn.test/icon.png", 			picURL:  "https://cdn.test/s1.png,https://cdn.test/s2.png",
  • Network accessline 309
    iconURL: "https://cdn.test/icon.png",
  • Network accessline 310
    picURL:  "https://cdn.test/s1.png,https://cdn.test/s2.png",

pkg/store/oppo/oppo.go

  • Executable scriptline 1
    Executable file
  • Network accessline 30
    store.Register("oppo", store.ConfigSchema{ 		Name:                     "oppo", 		ConsoleURL:               "https://open.oppomobile.com/new/developmentDoc/info?id=10998",
  • Network accessline 31
    Name:                     "oppo", 		ConsoleURL:               "https://open.oppomobile.com/new/developmentDoc/info?id=10998", 		SupportsScheduledRelease: true,
  • Network accessline 32
    ConsoleURL:               "https://open.oppomobile.com/new/developmentDoc/info?id=10998",
  • Access to secretsline 36
    [Credential-related source omitted]
  • Network accessline 154
    type Store struct { 	client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 155
    client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default 	clientID     string
  • Network accessline 156
    uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Access to secretsline 166
    [Credential-related source omitted]
  • Access to secretsline 168
    [Credential-related source omitted]
  • Network accessline 171
    client := newAPIClient("https://oop-openapi-cn.heytapmobi.com")
  • Access to secretsline 267
    [Credential-related source omitted]
  • Access to secretsline 276
    [Credential-related source omitted]
  • Access to secretsline 282
    [Credential-related source omitted]
  • Network accessline 557
    Data uploadResultData `json:"data"` 	} 	resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 558
    } 	resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{ 		Method: http.MethodPost,
  • Network accessline 559
    resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 661
    const oppoConsoleURL = "https://open.oppomobile.com"
  • Access to secretsline 772
    [Credential-related source omitted]
  • Access to secretsline 849
    [Credential-related source omitted]

pkg/store/oppo/oppo_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 302
    } 		wantAPKs := []apkInfo{ 			{URL: "https://cdn.test/helloworld.apk", MD5: "md5", CpuCode: 32},
  • Network accessline 303
    wantAPKs := []apkInfo{ 			{URL: "https://cdn.test/helloworld.apk", MD5: "md5", CpuCode: 32}, 			{URL: "https://cdn.test/app64.apk", MD5: "md5", CpuCode: 64},
  • Network accessline 304
    {URL: "https://cdn.test/helloworld.apk", MD5: "md5", CpuCode: 32},
  • Network accessline 305
    {URL: "https://cdn.test/app64.apk", MD5: "md5", CpuCode: 64},
  • Network accessline 308
    t.Errorf("remote=%v: apk_url = %+v, want %+v", remote, apks, wantAPKs) 		} 		if want := "https://cdn.test/" + icon.name; upd.Get("icon_url") != want {
  • Network accessline 309
    } 		if want := "https://cdn.test/" + icon.name; upd.Get("icon_url") != want { 			t.Errorf("remote=%v: icon_url = %q, want %q", remote, upd.Get("icon_url"), want)
  • Network accessline 310
    if want := "https://cdn.test/" + icon.name; upd.Get("icon_url") != want {
  • Access to secretsline 511
    [Credential-related source omitted]

pkg/store/oppo/replay_test.go

  • Executable scriptline 1
    Executable file
  • Access to secretsline 23
    [Credential-related source omitted]
  • Access to secretsline 40
    [Credential-related source omitted]

pkg/store/oppo/testdata/audit-withdrawn.trace.jsonl

  • Network accessline 1
    [Credential-related source omitted]
  • Access to secretsline 1
    [Credential-related source omitted]
  • Network accessline 2
    [Credential-related source omitted]
  • Access to secretsline 2
    [Credential-related source omitted]

pkg/store/pgyer/pgyer.go

  • Executable scriptline 1
    Executable file
  • Network accessline 20
    store.Register("pgyer", store.ConfigSchema{ 		Name:       "pgyer", 		ConsoleURL: "https://www.pgyer.com/doc/view/app_upload",
  • Network accessline 21
    Name:       "pgyer", 		ConsoleURL: "https://www.pgyer.com/doc/view/app_upload", 		Fields: []store.FieldSchema{
  • Network accessline 22
    ConsoleURL: "https://www.pgyer.com/doc/view/app_upload",
  • Access to secretsline 24
    [Credential-related source omitted]
  • Network accessline 42
    type Store struct { 	client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 43
    client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default 	apiKey       string
  • Network accessline 44
    uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Access to secretsline 49
    [Credential-related source omitted]
  • Access to secretsline 51
    [Credential-related source omitted]
  • Network accessline 54
    client := resty.New(). 		SetBaseURL("https://www.pgyer.com/apiv2")
  • Network accessline 55
    SetBaseURL("https://www.pgyer.com/apiv2")
  • Network accessline 118
    resp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 181
    } 	} 	return fmt.Errorf("build processing timed out (uploaded successfully, check pgyer dashboard at https://www.pgyer.com/manage/apps)")
  • Network accessline 182
    } 	return fmt.Errorf("build processing timed out (uploaded successfully, check pgyer dashboard at https://www.pgyer.com/manage/apps)") }
  • Network accessline 183
    return fmt.Errorf("build processing timed out (uploaded successfully, check pgyer dashboard at https://www.pgyer.com/manage/apps)")
  • Access to secretsline 197
    [Credential-related source omitted]

pkg/store/pgyer/pgyer_test.go

  • Executable scriptline 1
    Executable file

pkg/store/registry.go

  • Executable scriptline 1
    Executable file

pkg/store/samsung/audit_test.go

  • Executable scriptline 1
    Executable file

pkg/store/samsung/auth_test.go

  • Executable scriptline 1
    Executable file

pkg/store/samsung/binary_test.go

  • Executable scriptline 1
    Executable file

pkg/store/samsung/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/samsung/pem_test.go

  • Executable scriptline 1
    Executable file

pkg/store/samsung/samsung.go

  • Executable scriptline 1
    Executable file
  • Network accessline 33
    store.Register("samsung", store.ConfigSchema{ 		Name:                     "samsung", 		ConsoleURL:               "https://seller.samsungapps.com",
  • Network accessline 34
    Name:                     "samsung", 		ConsoleURL:               "https://seller.samsungapps.com", 		SupportsScheduledRelease: true,
  • Network accessline 35
    ConsoleURL:               "https://seller.samsungapps.com",
  • Network accessline 220
    uploadClient *http.Client
  • Network accessline 267
    const samsungBaseURL = "https://devapi.samsungapps.com"
  • Network accessline 302
    var uploadClient *http.Client
  • Network accessline 307
    } 		client.SetProxy(proxy) 		uploadClient = &http.Client{
  • Network accessline 308
    client.SetProxy(proxy) 		uploadClient = &http.Client{ 			Transport: &http.Transport{Proxy: http.ProxyURL(pu)},
  • Network accessline 309
    uploadClient = &http.Client{ 			Transport: &http.Transport{Proxy: http.ProxyURL(pu)}, 			Timeout:   30 * time.Minute, // large APKs; match httpx's default
  • Network accessline 624
    httpResp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{

pkg/store/samsung/version_test.go

  • Executable scriptline 1
    Executable file

pkg/store/scheduled_test.go

  • Executable scriptline 1
    Executable file

pkg/store/script/script.go

  • Executable scriptline 1
    Executable file

pkg/store/store.go

  • Executable scriptline 1
    Executable file

pkg/store/tencent/listing_fetch.go

  • Executable scriptline 1
    Executable file

pkg/store/tencent/listing_fetch_test.go

  • Executable scriptline 1
    Executable file

pkg/store/tencent/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/tencent/tencent.go

  • Executable scriptline 1
    Executable file
  • Network accessline 33
    var cosClient = &http.Client{}
  • Network accessline 36
    store.Register("tencent", store.ConfigSchema{ 		Name:                     "tencent", 		ConsoleURL:               "https://wikinew.open.qq.com/index.html#/iwiki/4015262492",
  • Network accessline 37
    Name:                     "tencent", 		ConsoleURL:               "https://wikinew.open.qq.com/index.html#/iwiki/4015262492", 		SupportsScheduledRelease: true,
  • Network accessline 38
    ConsoleURL:               "https://wikinew.open.qq.com/index.html#/iwiki/4015262492",
  • Network accessline 91
    const baseURL = "https://p.open.qq.com/open_file/developer_api"
  • Network accessline 93
    type Store struct { 	client       *resty.Client 	cos          *http.Client // the COS PUT when recording; nil = cosClient
  • Network accessline 94
    client       *resty.Client 	cos          *http.Client // the COS PUT when recording; nil = cosClient 	userID       string
  • Network accessline 95
    cos          *http.Client // the COS PUT when recording; nil = cosClient
  • Network accessline 348
    cos = cosClient 	} 	httpResp, err := httpx.DoUpload(ctx, httpx.FileRequest{
  • Network accessline 349
    } 	httpResp, err := httpx.DoUpload(ctx, httpx.FileRequest{ 		Method:   http.MethodPut,
  • Network accessline 350
    httpResp, err := httpx.DoUpload(ctx, httpx.FileRequest{
  • Network accessline 497
    const storePageBaseURL = "https://sj.qq.com/appdetail/"
  • Network accessline 502
    var storePageClient = &http.Client{Timeout: 15 * time.Second}

pkg/store/tencent/tencent_test.go

  • Executable scriptline 1
    Executable file

pkg/store/vivo/listing_fetch.go

  • Executable scriptline 1
    Executable file

pkg/store/vivo/listing_fetch_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 32
    s, method := vivoQueryStore(t, `{"code":0,"subCode":"0","msg":"成功","data":{ 		"packageName":"com.test.test","status":3,"versionCode":"12","versionName":"1.2", 		"icon":"https://img.test/icon.png",
  • Network accessline 33
    "packageName":"com.test.test","status":3,"versionCode":"12","versionName":"1.2", 		"icon":"https://img.test/icon.png", 		"detailDesc":"应用介绍","simpleDesc":"一句话简介",
  • Network accessline 34
    "icon":"https://img.test/icon.png",
  • Network accessline 35
    "detailDesc":"应用介绍","simpleDesc":"一句话简介", 		"screenshot":"https://img.test/1.png,https://img.test/2.png, https://img.test/3.png", 		"updateDesc":"应用更新内容介绍"}}`)
  • Network accessline 36
    "screenshot":"https://img.test/1.png,https://img.test/2.png, https://img.test/3.png",
  • Network accessline 44
    t.Errorf("method = %q", *method) 	} 	if got.Store != "vivo" || got.Brief != "一句话简介" || got.Description != "应用介绍" || got.Icon != "https://img.test/icon.png" {
  • Network accessline 45
    } 	if got.Store != "vivo" || got.Brief != "一句话简介" || got.Description != "应用介绍" || got.Icon != "https://img.test/icon.png" { 		t.Errorf("listing = %+v", got)
  • Network accessline 46
    if got.Store != "vivo" || got.Brief != "一句话简介" || got.Description != "应用介绍" || got.Icon != "https://img.test/icon.png" {
  • Network accessline 47
    t.Errorf("listing = %+v", got) 	} 	if want := []string{"https://img.test/1.png", "https://img.test/2.png", "https://img.test/3.png"}; !reflect.DeepEqual(got.Screenshots, want) {
  • Network accessline 48
    } 	if want := []string{"https://img.test/1.png", "https://img.test/2.png", "https://img.test/3.png"}; !reflect.DeepEqual(got.Screenshots, want) { 		t.Errorf("screenshots = %v", got.Screenshots)
  • Network accessline 49
    if want := []string{"https://img.test/1.png", "https://img.test/2.png", "https://img.test/3.png"}; !reflect.DeepEqual(got.Screenshots, want) {

pkg/store/vivo/listing_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 201
    req := &store.UploadRequest{ 				FilePath:     writeAPK(t, dir, "app.apk"), 				SourceURL:    "https://oss.example.com/app.apk",
  • Network accessline 202
    FilePath:     writeAPK(t, dir, "app.apk"), 				SourceURL:    "https://oss.example.com/app.apk", 				PackageName:  "com.example",
  • Network accessline 203
    SourceURL:    "https://oss.example.com/app.apk",
  • Network accessline 209
    if tt.split { 				req.File64Path = writeAPK(t, dir, "app64.apk") 				req.Source64URL = "https://oss.example.com/app64.apk"
  • Network accessline 210
    req.File64Path = writeAPK(t, dir, "app64.apk") 				req.Source64URL = "https://oss.example.com/app64.apk" 			}
  • Network accessline 211
    req.Source64URL = "https://oss.example.com/app64.apk"
  • Network accessline 304
    req := &store.UploadRequest{ 		FilePath:     writeAPK(t, t.TempDir(), "app.apk"), 		SourceURL:    "https://oss.example.com/app.apk",
  • Network accessline 305
    FilePath:     writeAPK(t, t.TempDir(), "app.apk"), 		SourceURL:    "https://oss.example.com/app.apk", 		PackageName:  "com.example",
  • Network accessline 306
    SourceURL:    "https://oss.example.com/app.apk",

pkg/store/vivo/replay_test.go

  • Executable scriptline 1
    Executable file

pkg/store/vivo/testdata/audit-withdrawn.trace.jsonl

  • Network accessline 1
    {"seq":1,"time":"2026-01-01T00:00:00Z","store":"vivo","method":"POST","url":"https://developer-api.vivo.com.cn/router/rest?access_key=sample&format=json&method=app.query.details&packageName=com.example.app&sign=%5BREDACTED+64%5D&sign_method

pkg/store/vivo/trace_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 31
    answer := func(method, body string) httptrace.Exchange { 		return httptrace.Exchange{ 			Method: "POST", URL: "https://developer-api.vivo.com.cn/router/rest?method=" + method, Status: 200,
  • Network accessline 32
    return httptrace.Exchange{ 			Method: "POST", URL: "https://developer-api.vivo.com.cn/router/rest?method=" + method, Status: 200, 			Response: &httptrace.Message{Headers: map[string]string{"Content-Type": "application/json"}, JSON: json.Raw
  • Network accessline 33
    Method: "POST", URL: "https://developer-api.vivo.com.cn/router/rest?method=" + method, Status: 200,

pkg/store/vivo/vivo.go

  • Executable scriptline 1
    Executable file
  • Network accessline 29
    const ( 	vivoBaseURL        = "https://developer-api.vivo.com.cn/router/rest"
  • Network accessline 30
    vivoBaseURL        = "https://developer-api.vivo.com.cn/router/rest"
  • Network accessline 31
    vivoSandboxBaseURL = "https://sandbox-developer-api.vivo.com.cn/router/rest"
  • Network accessline 35
    store.RegisterWithEnvironment("vivo", store.ConfigSchema{ 		Name:                     "vivo", 		ConsoleURL:               "https://dev.vivo.com.cn/documentCenter/doc/326",
  • Network accessline 36
    Name:                     "vivo", 		ConsoleURL:               "https://dev.vivo.com.cn/documentCenter/doc/326", 		SupportsScheduledRelease: true,
  • Network accessline 37
    ConsoleURL:               "https://dev.vivo.com.cn/documentCenter/doc/326",
  • Network accessline 136
    type Store struct { 	client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 137
    client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default 	baseURL      string
  • Network accessline 138
    uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 467
    queryVals.Set(k, v) 	} 	httpResp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{
  • Network accessline 468
    } 	httpResp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{ 		Method:   http.MethodPost,
  • Network accessline 469
    httpResp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{

pkg/store/vivo/vivo_test.go

  • Executable scriptline 1
    Executable file
  • Network accessline 313
    req := &store.UploadRequest{ 				FilePath:    path32, 				SourceURL:   "https://oss.example.com/app.apk",
  • Network accessline 314
    FilePath:    path32, 				SourceURL:   "https://oss.example.com/app.apk", 				PackageName: "com.example",
  • Network accessline 315
    SourceURL:   "https://oss.example.com/app.apk",
  • Network accessline 320
    want := map[string]string{"apkUrl": req.SourceURL, "apkMd5": md5Hex(t, path32)} 			if split { 				req.File64Path, req.Source64URL = path64, "https://oss.example.com/app64.apk"
  • Network accessline 321
    if split { 				req.File64Path, req.Source64URL = path64, "https://oss.example.com/app64.apk" 				method = "app.update.subpackage.app"
  • Network accessline 322
    req.File64Path, req.Source64URL = path64, "https://oss.example.com/app64.apk"

pkg/store/xiaomi/listing.go

  • Executable scriptline 1
    Executable file

pkg/store/xiaomi/listing_test.go

  • Executable scriptline 1
    Executable file

pkg/store/xiaomi/replay_test.go

  • Executable scriptline 1
    Executable file

pkg/store/xiaomi/testdata/audit-live.trace.jsonl

  • Network accessline 1
    {"seq":1,"time":"2026-01-01T00:00:00Z","store":"xiaomi","method":"POST","url":"https://api.developer.xiaomi.com/devupload/dev/query","request":{"headers":{"Content-Type":"application/x-www-form-urlencoded"},"form":{"RequestData":["{\"packag

pkg/store/xiaomi/xiaomi.go

  • Executable scriptline 1
    Executable file
  • Network accessline 35
    const xiaomiBaseURL = "https://api.developer.xiaomi.com/devupload"
  • Network accessline 38
    store.Register("xiaomi", store.ConfigSchema{ 		Name:                     "xiaomi", 		ConsoleURL:               "https://dev.mi.com/xiaomihyperos/documentation/detail?pId=1134",
  • Network accessline 39
    Name:                     "xiaomi", 		ConsoleURL:               "https://dev.mi.com/xiaomihyperos/documentation/detail?pId=1134", 		SupportsScheduledRelease: true,
  • Network accessline 40
    ConsoleURL:               "https://dev.mi.com/xiaomihyperos/documentation/detail?pId=1134",
  • Network accessline 107
    type Store struct { 	client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 108
    client       *resty.Client 	uploadClient *http.Client // streamed file uploads; nil = httpx's default 	baseURL      string
  • Network accessline 109
    uploadClient *http.Client // streamed file uploads; nil = httpx's default
  • Network accessline 373
    pushResp, err := httpx.DoMultipart(ctx, httpx.MultipartRequest{

pkg/store/xiaomi/xiaomi_test.go

  • Executable scriptline 1
    Executable file

pkg/telemetry/telemetry.go

  • Executable scriptline 1
    Executable file
  • Network accessline 19
    var endpoint = "https://apkgo.baici.tech/telemetry/v1/events"
  • Network accessline 79
    return 		} 		client := &http.Client{Timeout: 5 * time.Second}
  • Network accessline 80
    } 		client := &http.Client{Timeout: 5 * time.Second} 		resp, err := client.Post(endpoint, "application/json", bytes.NewReader(body))
  • Network accessline 81
    client := &http.Client{Timeout: 5 * time.Second}

pkg/telemetry/telemetry_test.go

  • Executable scriptline 1
    Executable file

pkg/update/check.go

  • Executable scriptline 1
    Executable file
  • Network accessline 15
    const ( 	releaseAPI   = "https://api.github.com/repos/KevinGong2013/apkgo/releases/latest"
  • Network accessline 16
    releaseAPI   = "https://api.github.com/repos/KevinGong2013/apkgo/releases/latest"
  • Network accessline 79
    func fetchLatest() (string, error) { 	client := &http.Client{Timeout: 5 * time.Second}
  • Network accessline 80
    client := &http.Client{Timeout: 5 * time.Second}

pkg/uploader/events.go

  • Executable scriptline 1
    Executable file

pkg/uploader/events_test.go

  • Executable scriptline 1
    Executable file

pkg/uploader/manager.go

  • Executable scriptline 1
    Executable file

pkg/uploader/mpb_reporter.go

  • Executable scriptline 1
    Executable file

pkg/uploader/mpb_reporter_test.go

  • Executable scriptline 1
    Executable file

pkg/uploader/ndjson_reporter.go

  • Executable scriptline 1
    Executable file

pkg/uploader/ndjson_reporter_test.go

  • Executable scriptline 1
    Executable file

pkg/uploader/uploader.go

  • Executable scriptline 1
    Executable file

pkg/uploader/uploader_test.go

  • Executable scriptline 1
    Executable file

How the signals fit together

Facts from a static read of the files at the pinned commit. They describe what the code does, not why.

Some files could not be read; the facts below still hold.

Combined signals: 1 fact
  • Passes content downloaded from apkgo.baici.tech to an interpreterSKILL.md:34High confidence
Declared and executed: 9 facts
Signal confidence: 490 facts

and 440 more

Only the first 500 facts are listed.

Works with

Agent compatibility, from the files in this repository
AgentStatusEvidenceInstall to
Claude CodeNativePath .claude/skills/apkgo-cli-usage/SKILL.md.claude/skills/<skill-name>/
CodexCompatibleStandard SKILL.md SKILL.md.agents/skills/<skill-name>/
CursorCompatibleStandard SKILL.md SKILL.md.cursor/skills/<skill-name>/
Gemini CLICompatibleStandard SKILL.md SKILL.md.gemini/skills/<skill-name>/
GitHub CopilotCompatibleStandard SKILL.md SKILL.md.github/skills/<skill-name>/
OpenCodeCompatibleStandard SKILL.md SKILL.md.opencode/skills/<skill-name>/
  • Native The repository ships a manifest, folder or frontmatter field for this agent.
  • Compatible A standard SKILL.md that this agent can read.
  • Unknown No evidence either way.

Derived automatically from paths, manifests and frontmatter. Not tested on each agent.