From 588c99df7fd535ec1a2592f519bde84aca9ade31 Mon Sep 17 00:00:00 2001 From: max Date: Fri, 21 Aug 2026 16:53:01 +0800 Subject: [PATCH 1/4] ci: add GitHub Actions workflow for automated releases --- .github/workflows/release.yml | 74 +++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..fad8f72 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,74 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Git tag to release (e.g. v2.6.10)' + required: true + +permissions: + contents: write + +jobs: + build-and-release: + name: Build and Create GitHub Release + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ inputs.tag || github.ref }} + + - name: Set up JDK 8 + uses: actions/setup-java@v4 + with: + java-version: '8' + distribution: 'zulu' + cache: maven + + - name: Run Maven verify + run: mvn --batch-mode verify -DskipITs -Dgpg.skip + + - name: Build SDK Artifacts + run: mvn --batch-mode clean package -Pshade-all -DskipTests + + - name: Collect release assets + run: | + mkdir -p release-assets + cp target/qingstor.sdk.java-*.jar release-assets/ + rm -f release-assets/*-sources.jar release-assets/*-javadoc.jar + ls -la release-assets/ + + - name: Extract Release Notes from CHANGELOG.md + id: changelog + run: | + TAG="${{ inputs.tag || github.ref_name }}" + VERSION="${TAG#v}" + sed -n "/^## \[v\?${VERSION}\]/,/^## \[v\?[0-9]/p" CHANGELOG.md | sed '1d;$d' > RELEASE_NOTES.md + if [ ! -s RELEASE_NOTES.md ]; then + echo "Release notes for ${TAG} not found in CHANGELOG.md, fallback to auto-generate." + rm -f RELEASE_NOTES.md + fi + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ inputs.tag || github.ref_name }} + run: | + RELEASE_ARGS=( + "$TAG" + release-assets/* + --title "Release $TAG" + ) + if [ -s RELEASE_NOTES.md ]; then + RELEASE_ARGS+=(--notes-file RELEASE_NOTES.md) + else + RELEASE_ARGS+=(--generate-notes) + fi + gh release create "${RELEASE_ARGS[@]}" From 87db00e6f9df7cead25df419a09c9b09d45108ce Mon Sep 17 00:00:00 2001 From: max Date: Fri, 21 Aug 2026 16:53:09 +0800 Subject: [PATCH 2/4] docs: update Maven Central badge and links --- README.md | 2 +- README_zh-CN.md | 2 +- docs/install.md | 2 +- docs/install_zh-CN.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 411d4da..e3da9c4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # QingStor SDK for Java -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.yunify/qingstor.sdk.java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.yunify/qingstor.sdk.java) +[![Maven Central](https://img.shields.io/maven-central/v/com.yunify/qingstor.sdk.java.svg)](https://central.sonatype.com/artifact/com.yunify/qingstor.sdk.java) ![Build Status](https://github.com/qingstor/qingstor-sdk-java/workflows/Unit%20Test/badge.svg) [![API Reference](https://img.shields.io/badge/api-reference-green.svg)](https://docsv4.qingcloud.com/user_guide/storage/object_storage/) [![License](https://img.shields.io/badge/license-apache%20v2-blue.svg)](https://github.com/yunify/qingstor-sdk-Java/blob/master/LICENSE) diff --git a/README_zh-CN.md b/README_zh-CN.md index ed67f27..54c2684 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -1,6 +1,6 @@ # QingStor SDK for Java -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.yunify/qingstor.sdk.java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.yunify/qingstor.sdk.java) +[![Maven Central](https://img.shields.io/maven-central/v/com.yunify/qingstor.sdk.java.svg)](https://central.sonatype.com/artifact/com.yunify/qingstor.sdk.java) ![Build Status](https://github.com/qingstor/qingstor-sdk-java/workflows/Unit%20Test/badge.svg) [![API Reference](https://img.shields.io/badge/api-reference-green.svg)](https://docsv4.qingcloud.com/user_guide/storage/object_storage/) [![License](https://img.shields.io/badge/license-apache%20v2-blue.svg)](https://github.com/yunify/qingstor-sdk-Java/blob/master/LICENSE) diff --git a/docs/install.md b/docs/install.md index b0d540c..b11dd5b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -26,6 +26,6 @@ Maven: ``` -[Latest SDK jar](https://maven-badges.herokuapp.com/maven-central/com.yunify/qingstor.sdk.java) are available from Maven Central. +[Latest SDK jar](https://central.sonatype.com/artifact/com.yunify/qingstor.sdk.java) are available from Maven Central. If you want to use a fatJar(with all deps included), you can download it from our [release page](https://github.com/qingstor/qingstor-sdk-java/releases/latest). diff --git a/docs/install_zh-CN.md b/docs/install_zh-CN.md index 5086fcb..a3894e6 100644 --- a/docs/install_zh-CN.md +++ b/docs/install_zh-CN.md @@ -26,6 +26,6 @@ Maven: ``` -[最新的 SDK jar](https://maven-badges.herokuapp.com/maven-central/com.yunify/qingstor.sdk.java) 可以从 Maven Central 获取. +[最新的 SDK jar](https://central.sonatype.com/artifact/com.yunify/qingstor.sdk.java) 可以从 Maven Central 获取. 如果你需要使用 fatJar(所有依赖打包在一起), 你可以从我们的 [发布页面](https://github.com/qingstor/qingstor-sdk-java/releases/latest) 下载. From 2b486fd69e9fec96b1308beda488d64da16912e4 Mon Sep 17 00:00:00 2001 From: max Date: Fri, 21 Aug 2026 16:53:11 +0800 Subject: [PATCH 3/4] docs: add maintainer release guide and repository guidelines --- AGENTS.md | 35 ++++++++++++++++ docs/release.md | 103 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 AGENTS.md create mode 100644 docs/release.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..2cca863 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,35 @@ +# Repository Guidelines + +## Project Structure & Module Organization + +This is a Maven-based Java SDK for QingStor. Main source lives in `src/main/java/com/qingstor/sdk`, with resources in `src/main/resources`. Unit tests live under `src/test/java/com/qingstor/sdk`; integration and Cucumber tests live under `src/test/java/integration/cucumber` and use feature files from `tests/features`. API specs are in `specs/qingstor`, code-generation templates are in `template`, and user-facing documentation is in `docs`. Architecture/release decisions belong in `docs/adr`, with implementation specs in `docs/specs`. + +## Build, Test, and Development Commands + +- `mvn test`: run unit tests, excluding integration tests. +- `mvn verify -DskipITs -Dgpg.skip`: run the CI-style Maven verify phase without signing. +- `mvn spotless:check`: verify formatting of Java and Markdown files. +- `mvn spotless:apply`: format Java and Markdown files according to repo style. +- `mvn integration-test`: run service/integration tests; configure local credentials from `tests/config.yaml.example` or `tests/test_config.yaml.example`. +- `mvn package -Prelease`: build normal jar, sources, and javadocs. +- `mvn clean -Pshade-all -DskipTests package`: build the shaded jar at `target/qingstor.sdk.java--shaded.jar`. +- `make generate`: regenerate service code from Swagger specs using `snips`, then apply formatting. + +## Coding Style & Naming Conventions + +Java targets source/bytecode level 8. Formatting is managed by Spotless with google-java-format `1.7` in AOSP style and the header in `spotless.license.java`; run `mvn spotless:apply` before committing generated or manually edited Java. Use package names under `com.qingstor.sdk`. Keep test classes named `*Test` and integration/Cucumber classes grouped under the existing integration package. + +## Testing Guidelines + +Use JUnit 4 for unit tests and Cucumber for behavior/integration coverage. Prefer focused unit tests for utility and model behavior; reserve integration tests for QingStor service workflows that require credentials. Do not commit local secrets or generated test config files. + +## Commit & Pull Request Guidelines + +Recent commits use concise, imperative subjects with optional prefixes, for example `fix(delete-obj): ...`, `deps: ...`, `chore: ...`, and `Bump version to ...`. Keep commits scoped to one concern. Pull requests should describe the behavior change, list verification commands run, link related issues when available, and call out release-impacting changes such as dependency updates, Central publishing, or shaded jar behavior. + +## Release Guidelines + +- **Release Guide & SOP**: See [`docs/release.md`](docs/release.md) for the complete, step-by-step maintainer release guide. +- **Version Bump Checklist**: Update version across `pom.xml`, `src/main/resources/version.properties`, `docs/install.md`, `docs/install_zh-CN.md`, and document changes in `CHANGELOG.md`. +- **GitHub Releases**: Automated via `.github/workflows/release.yml`. Pushing a tag `v` automatically verifies, builds the standard JAR + shaded JAR, extracts notes from `CHANGELOG.md`, and creates the GitHub Release with assets attached. +- **Maven Central Publishing**: Use `mvn clean deploy -Prelease` (do NOT activate `shade-all`) to upload signed standard artifacts to Sonatype Central Portal, then confirm deployment in the portal. diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 0000000..ed683b7 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,103 @@ +# Release Guide (发布操作手册) + +本文档面向 QingStor Java SDK 维护者,详细记录了标准版本发布操作流程 (Release SOP)。 + +--- + +## 流程概览 + +```mermaid +flowchart TD + A["1. 更新版本号与 CHANGELOG.md"] --> B["2. 本地测试与代码格式校验"] + B --> C["3. 创建 release 分支并提 PR: gh pr create --fill"] + C --> D["4. 等待 CI 通过并 Rebase Merge"] + D --> E["5. master 打 Tag 并推送: git push origin v"] + E --> F["【自动】GitHub Actions 自动构建并发布 GitHub Release"] + D --> G["6. 本地部署 Maven Central: mvn clean deploy -Prelease"] + G --> H["7. Sonatype Central Portal 确认并发布"] +``` + +--- + +## 详细步骤 + +### 第一步:版本号更新与本地校验 + +1. **更新版本号清单 (Version Bump)**: + - `pom.xml`: `X.Y.Z` + - `src/main/resources/version.properties`: `version=X.Y.Z` + - `docs/install.md`: Maven 依赖版本 + - `docs/install_zh-CN.md`: Maven 依赖版本 + - `CHANGELOG.md`: 补充 `## [vX.Y.Z] - YYYY-MM-DD` 对应更新日志 +2. **本地执行验证**: + ```bash + mvn spotless:apply + mvn test + mvn verify -DskipITs -Dgpg.skip + ``` + +--- + +### 第二步:创建发布分支并提交 PR + +```bash +# 1. 切出发布分支并提交 +git checkout -b release/v +git push -u origin release/v + +# 2. 使用 gh 创建 Pull Request +gh pr create --fill +``` + +--- + +### 第三步:等待 CI 校验并合并 + +```bash +# 1. 检查 CI 运行状态 +gh pr checks + +# 2. 执行 Rebase Merge(管理员使用 --admin 绕过审批限制立即合并) +gh pr merge --rebase --delete-branch --admin +``` + +> **说明**:仓库配置了 1 位 Reviewer 审批规则,维护者使用 `--admin` 参数可直接以管理员权限绕过限制完成合并(等同于网页端勾选 Bypass rules)。 + +--- + +### 第四步:打 Tag 触发 GitHub Release 自动化发布 + +```bash +# 1. 切换回 master 并拉取最新合并代码 +git checkout master +git pull origin master + +# 2. 打 Tag 并推送到 GitHub 远程仓库 +git tag -a v -m "Release v" +git push origin v + +# 3. 监控 GitHub Actions 自动化发布进度 +gh run watch +``` + +> **自动化说明**: +> GitHub Actions (`.github/workflows/release.yml`) 会在检测到 `v*` Tag 后自动触发: +> - 使用 JDK 8 环境执行验证 +> - 自动打包生成标准 Jar 与 Shaded Jar +> - 自动从 `CHANGELOG.md` 提取当前版本的 Release Notes +> - 自动创建 GitHub Release 并附加两个 Jar 产物 + +--- + +### 第五步:发布至 Maven Central + +在具备 GPG 私钥与 Sonatype 认证配置的环境下执行: + +```bash +# 本地执行构建、签名与上传(切勿激活 shade-all Profile) +mvn clean deploy -Prelease +``` + +1. 上传成功后,登录 [Sonatype Central Portal](https://central.sonatype.com/)。 +2. 在 **Deployments** 列表中确认当前部署包校验状态为 **Validated**。 +3. 点击 **Publish** 按钮确认发布(约 15~30 分钟内全球镜像同步生效)。 From 12a9338f3bcaa64b75fa6b09983532c7139f7df8 Mon Sep 17 00:00:00 2001 From: max Date: Fri, 21 Aug 2026 17:02:53 +0800 Subject: [PATCH 4/4] Bump version to 2.6.10 --- CHANGELOG.md | 17 +++++++++++++++++ docs/install.md | 2 +- docs/install_zh-CN.md | 2 +- pom.xml | 2 +- src/main/resources/version.properties | 2 +- 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbaed02..5c70679 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to QingStor SDK for JAVA will be documented in this file. +## [v2.6.10] - 2026-08-21 + +### Added + +- Add GitHub Actions workflow for automated releases on tag push. +- Add maintainer release guide in `docs/release.md` and repository guidelines in `AGENTS.md`. + +### Changed + +- Improve error logging in `QSOkHttpRequestClient` to include stack traces. +- Update Maven Central badge and documentation links to use Shields.io and Sonatype Central Portal. + +### Fixed + +- Preserve root cause and enhance error message formatting in `QSException`. +- Preserve root cause exception on request execution and callback parsing failures in `QSOkHttpRequestClient`. + ## [v2.6.9] - 2026-08-04 ### Changed diff --git a/docs/install.md b/docs/install.md index b11dd5b..26067da 100644 --- a/docs/install.md +++ b/docs/install.md @@ -22,7 +22,7 @@ Maven: com.yunify qingstor.sdk.java - 2.6.9 + 2.6.10 ``` diff --git a/docs/install_zh-CN.md b/docs/install_zh-CN.md index a3894e6..bee100b 100644 --- a/docs/install_zh-CN.md +++ b/docs/install_zh-CN.md @@ -22,7 +22,7 @@ Maven: com.yunify qingstor.sdk.java - 2.6.9 + 2.6.10 ``` diff --git a/pom.xml b/pom.xml index 1b23c5d..3c8c36a 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.yunify qingstor.sdk.java - 2.6.9 + 2.6.10 Qingcloud Qingstor SDK for Java The official QingStor SDK for the Java programming language. https://www.qingcloud.com/products/objectstorage/ diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties index d1dd696..e1a5174 100644 --- a/src/main/resources/version.properties +++ b/src/main/resources/version.properties @@ -1 +1 @@ -version=2.6.9 +version=2.6.10