Skip to content

Comments

fix: fix release pipeline and automate GitHub release creation#291

Merged
jakubuid merged 3 commits intodevelopfrom
fix/release-pipeline-automation
Feb 12, 2026
Merged

fix: fix release pipeline and automate GitHub release creation#291
jakubuid merged 3 commits intodevelopfrom
fix/release-pipeline-automation

Conversation

@jakubuid
Copy link
Collaborator

Summary

  • Root cause fix: Close staging repositories before uploading to Central Portal (OSSRH requires closed state)
  • Fix POS routing: POS publishes under com.walletconnect but was routing to the reown staging repo — now correctly targets walletconnect
  • Fix POM URL typo: reown-conreown-com in publish-module-java.gradle.kts (4 occurrences)
  • Replace fragile JSON parsing: Swap regex-based parsing with groovy.json.JsonSlurper in build.gradle.kts
  • Add Pay/POS to artifact polling: New ArtifactCheck data class supports different Maven groups (com/reown vs com/walletconnect)
  • Add retry logic: Portal uploads now retry 3 times with 10s delay between attempts
  • Fail loudly: Empty repos and no-closed repos now throw with actionable error messages instead of silently exiting
  • Automate GitHub release: CI workflow now extracts BOM version, creates a git tag (BOM_{version}), and creates a GitHub release with auto-generated notes
  • Rewrite manual release workflow: ci_github_release.yml now accepts a version input and uses gh CLI (replaces deprecated actions/create-release@v1)

Architecture

flowchart TD
    A[Push to master] --> B[Build & publish to Sonatype staging]
    B --> C["Close staging repos<br/>(NEW: closeReown + closeWalletconnect)"]
    C --> D[Upload closed repos to Central Portal]
    D --> E[Wait for Maven Central availability]
    E --> F["Extract BOM version<br/>(NEW)"]
    F --> G["Create git tag BOM_{version}<br/>(NEW)"]
    G --> H["Create GitHub Release<br/>(NEW)"]
    H --> I[Triggers downstream workflows]
    I --> J[ci_release_sample.yml]
    I --> K[slack_release_notifications]
Loading

Files Changed

File Change
buildSrc/.../release-scripts.gradle.kts POS → walletconnect repository
buildSrc/.../publish-module-java.gradle.kts reown-conreown-com (4 URLs)
build.gradle.kts JsonSlurper parsing, closed-only uploads, retry logic, Pay/POS polling
.github/workflows/ci_release_artifacts.yml Close repos step + automated release
.github/workflows/ci_github_release.yml Manual fallback with version input

Test plan

  • Verify POM URL fix: ./gradlew :foundation:generatePomFileForMavenJvmPublication — inspect POM for reown-com
  • Verify POS routing: ./gradlew releaseAllSDKs -Ptype=local — check POS publishes under com/walletconnect/pos/
  • Verify JSON parsing compiles: ./gradlew help (build script evaluation)
  • Full CI test: push version bump to master and monitor ci_release_artifacts.yml run
  • Manual fallback: trigger ci_github_release.yml with a version input

🤖 Generated with Claude Code

The release pipeline was broken at the closeAndReleaseMultipleRepositories
task — staging repos were uploaded while still open (OSSRH requires closed
state), JSON parsing used fragile regex, POS routed to the wrong staging
repo, and Pay/POS were missing from artifact availability polling.

Key fixes:
- Close staging repos before portal upload (root cause)
- Replace regex JSON parsing with groovy.json.JsonSlurper
- Route POS to walletconnect staging repository
- Fix reown-con → reown-com POM URL typo (publish-module-java)
- Add Pay/POS to Maven Central artifact polling with correct groups
- Add retry logic (3 attempts) to portal uploads
- Fail loudly on empty or no-closed staging repos
- Automate git tag + GitHub release in CI workflow
- Rewrite manual release workflow with version input and gh CLI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 11, 2026

Claude finished @jakubuid's task in 1m 29s —— View job


Review Complete

Found 3 issue(s)

Issue 1: Tag creation can fail but release still attempts

ID: ci_release-tag-race-8f3a
File: .github/workflows/ci_release_artifacts.yml:108-113
Severity: MEDIUM
Category: code_quality

Context:

  • Pattern: Tag creation at lines 108-113 has no error handling. If tag already exists (e.g., from failed previous run), git tag fails but workflow continues to release creation
  • Risk: GitHub release creation with gh release create (line 119) will fail cryptically if tag doesn't exist or already exists with different commit
  • Impact: Silent failures or duplicate tag conflicts causing workflow failures
  • Trigger: Re-running workflow after partial failure, or running workflow twice for same version

Recommendation: Add idempotency check:

- name: Create git tag
  run: |
    git config user.name "github-actions[bot]"
    git config user.email "github-actions[bot]@users.noreply.github.com"
    TAG="BOM_${{ steps.version.outputs.bom_version }}"
    if git rev-parse "$TAG" >/dev/null 2>&1; then
      echo "Tag $TAG already exists, skipping tag creation"
    else
      git tag "$TAG"
      git push origin "$TAG"
    fi

Issue 2: Incomplete license check validation

ID: publish-license-typo-2c4f
File: buildSrc/src/main/kotlin/publish-module-java.gradle.kts:47
Severity: LOW
Category: code_quality

Context:

  • Pattern: License URL at line 47 points to master branch (GitHub UI redirects to default branch, but programmatic access may not)
  • Risk: Maven Central validators or automated tools fetching license may fail if master != default branch
  • Impact: Publishing delays or validation warnings from Maven Central
  • Trigger: Repository renames default branch or programmatic license validation

Recommendation: Use branch-agnostic URL:

url.set("https://github.com/reown-com/reown-kotlin/blob/HEAD/LICENSE")

Issue 3: HTTP client resource leak in retry loop

ID: build-httpclient-leak-9a2c
File: build.gradle.kts:240-283
Severity: MEDIUM
Category: performance

Context:

  • Pattern: uploadRepositoryToPortal creates new CloseableHttpClient in retry loop (line 247) but doesn't close it until finally block (line 275). If early return at line 266 executes, client is closed, but if exception occurs before close, resources leak across retries
  • Risk: Socket exhaustion during retries (3 retries × N repos = many unclosed sockets if exceptions occur)
  • Impact: Gradle daemon can run out of file descriptors causing subsequent tasks to fail with "too many open files"
  • Trigger: Network timeouts or server errors during upload attempts

Recommendation: Use use block for automatic cleanup:

repeat(maxRetries) { attempt ->
    createHttpClient().use { client ->
        try {
            val httpPost = HttpPost(uploadUrl).apply {
                setHeader("Authorization", authHeader())
                setHeader("Content-Type", "application/json")
                entity = StringEntity("""{"publishing_type": "automatic"}""")
            }
            // ... rest of logic
        } catch (e: Exception) {
            lastException = e
            // ... rest of catch
        }
    }
    // Retry logic outside use block
}

Summary

Core improvements look solid:

  • ✅ JsonSlurper replaces fragile regex parsing
  • ✅ Closed-only uploads with proper validation
  • ✅ POM URL typo fixes complete
  • ✅ POS routing to walletconnect repo correct
  • ✅ Retry logic added for uploads

3 issues found, all non-blocking for merge but worth addressing to prevent runtime issues in CI.

Remove paths filter and module-change checks so pay e2e tests
run unconditionally on all PRs targeting develop/master.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Feb 12, 2026

Claude finished @jakubuid's task in 1m 27s —— View job


🔄 Incremental Review:

Tasks

  • Extract previous issue IDs
  • Read changed files
  • Verify status of previously reported issues
  • Check for new issues
  • Post review findings

Previous Issues Status

Issue 1: ci_release-tag-race-8f3a (Tag creation error handling) — ✅ STILL EXISTS
Lines 108-113 in ci_release_artifacts.yml still lack idempotency check for tag creation.

Issue 2: publish-license-typo-2c4f (License URL pointing to master) — ✅ STILL EXISTS
Line 47 in publish-module-java.gradle.kts still points to /blob/master/LICENSE.

Issue 3: build-httpclient-leak-9a2c (HTTP client resource leak) — ✅ STILL EXISTS
Lines 240-283 in build.gradle.kts still creates HTTP client in retry loop with potential resource leak on exception.


Found 3 issue(s)

Issue 1: Tag creation can fail but release still attempts

ID: ci_release-tag-race-8f3a
File: .github/workflows/ci_release_artifacts.yml:108-113
Severity: MEDIUM
Category: code_quality

Context:

  • Pattern: Tag creation at lines 108-113 has no error handling. If tag already exists (e.g., from failed previous run), git tag fails but workflow continues to release creation
  • Risk: GitHub release creation with gh release create (line 119) will fail cryptically if tag doesn't exist or already exists with different commit
  • Impact: Silent failures or duplicate tag conflicts causing workflow failures
  • Trigger: Re-running workflow after partial failure, or running workflow twice for same version

Recommendation: Add idempotency check:

- name: Create git tag
  run: |
    git config user.name "github-actions[bot]"
    git config user.email "github-actions[bot]@users.noreply.github.com"
    TAG="BOM_${{ steps.version.outputs.bom_version }}"
    if git rev-parse "$TAG" >/dev/null 2>&1; then
      echo "Tag $TAG already exists, skipping tag creation"
    else
      git tag "$TAG"
      git push origin "$TAG"
    fi

Issue 2: License URL points to master branch

ID: publish-license-typo-2c4f
File: buildSrc/src/main/kotlin/publish-module-java.gradle.kts:47
Severity: LOW
Category: code_quality

Context:

  • Pattern: License URL at line 47 points to master branch (GitHub UI redirects to default branch, but programmatic access may not)
  • Risk: Maven Central validators or automated tools fetching license may fail if master != default branch
  • Impact: Publishing delays or validation warnings from Maven Central
  • Trigger: Repository renames default branch or programmatic license validation

Recommendation: Use branch-agnostic URL:

url.set("https://github.com/reown-com/reown-kotlin/blob/HEAD/LICENSE")

Issue 3: HTTP client resource leak in retry loop

ID: build-httpclient-leak-9a2c
File: build.gradle.kts:240-283
Severity: MEDIUM
Category: performance

Context:

  • Pattern: uploadRepositoryToPortal creates new CloseableHttpClient in retry loop (line 247) but doesn't close it until finally block (line 275). If early return at line 266 executes, client is closed, but if exception occurs before close, resources leak across retries
  • Risk: Socket exhaustion during retries (3 retries × N repos = many unclosed sockets if exceptions occur)
  • Impact: Gradle daemon can run out of file descriptors causing subsequent tasks to fail with "too many open files"
  • Trigger: Network timeouts or server errors during upload attempts

Recommendation: Use use block for automatic cleanup:

repeat(maxRetries) { attempt ->
    createHttpClient().use { client ->
        try {
            val httpPost = HttpPost(uploadUrl).apply {
                setHeader("Authorization", authHeader())
                setHeader("Content-Type", "application/json")
                entity = StringEntity("""{"publishing_type": "automatic"}""")
            }
            // ... rest of logic
        } catch (e: Exception) {
            lastException = e
            // ... rest of catch
        }
    }
    // Retry logic outside use block
}

Summary

✅ No new issues found in latest commits. All 3 previously reported issues remain unresolved.

- Add idempotency check for git tag creation (skip if tag exists)
- Use `use` block for CloseableHttpClient in retry loop to prevent
  resource leaks on exceptions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jakubuid
Copy link
Collaborator Author

Addressed auto-review feedback:

  • Tag creation idempotency — added git rev-parse check; tag creation is now skipped if the tag already exists, preventing failures on workflow re-runs
  • HTTP client resource leak — replaced manual try/finally with createHttpClient().use { } block to guarantee cleanup on all code paths including early returns and exceptions

@claude
Copy link

claude bot commented Feb 12, 2026

Claude finished @jakubuid's task in 1m 1s —— View job


🔄 Incremental Review:

Tasks

  • Extract previous issue IDs
  • Read changed files
  • Verify status of previously reported issues
  • Check for new issues
  • Post review findings

Previous Issues Status

Issue 1: ci_release-tag-race-8f3a (Tag creation error handling) — ✅ RESOLVED
Lines 113-118 in ci_release_artifacts.yml now include git rev-parse check; tag creation is skipped if tag already exists.

Issue 2: publish-license-typo-2c4f (License URL pointing to master) — ❌ STILL EXISTS
Line 47 in publish-module-java.gradle.kts still points to /blob/master/LICENSE.

Issue 3: build-httpclient-leak-9a2c (HTTP client resource leak) — ✅ RESOLVED
Line 247 in build.gradle.kts now uses createHttpClient().use { } block with retry logic outside, guaranteeing cleanup on all paths.


Found 1 issue(s)

Issue 1: License URL points to master branch

ID: publish-license-typo-2c4f
File: buildSrc/src/main/kotlin/publish-module-java.gradle.kts:47
Severity: LOW
Category: code_quality

Context:

  • Pattern: License URL at line 47 points to master branch (GitHub UI redirects to default branch, but programmatic access may not)
  • Risk: Maven Central validators or automated tools fetching license may fail if master != default branch
  • Impact: Publishing delays or validation warnings from Maven Central
  • Trigger: Repository renames default branch or programmatic license validation

Recommendation: Use branch-agnostic URL:

url.set("https://github.com/reown-com/reown-kotlin/blob/HEAD/LICENSE")

Summary

✅ 2 of 3 previously reported issues resolved (tag idempotency + HTTP client leak)
❌ 1 previously reported issue remains (license URL)
✅ No new issues found in latest commits

@sonarqubecloud
Copy link

@jakubuid jakubuid merged commit 8a2dce9 into develop Feb 12, 2026
15 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Feb 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant