From 417b74cc5108d913c798ece04df304ddaab1fbbd Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Sun, 10 May 2026 22:23:25 +0800 Subject: [PATCH] refactor(ci): trigger Homebrew/Scoop publish on release event Move packages job from release.yml to publish-packages.yml, triggered by release published/released events. Keeps workflow_dispatch as a manual fallback. Now all external publishing (Homebrew, Scoop, 1Panel, QQ notify) triggers at the same time: when a prerelease is promoted to a full release. --- .github/workflows/publish-packages.yml | 5 +- .github/workflows/release.yml | 199 ------------------------- crates/dbx-core/src/connection.rs | 50 ++++++- 3 files changed, 46 insertions(+), 208 deletions(-) diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index 36d5b2373..07f1404f9 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -1,6 +1,8 @@ name: Publish Packages on: + release: + types: [published, released] workflow_dispatch: inputs: tag: @@ -19,11 +21,12 @@ jobs: publish: name: Publish to Homebrew & Scoop runs-on: ubuntu-latest + if: ${{ github.event_name == 'workflow_dispatch' || (!github.event.release.draft && !github.event.release.prerelease) }} steps: - name: Extract version from tag id: version run: | - TAG="${{ github.event.inputs.tag }}" + TAG="${{ github.event.release.tag_name || github.event.inputs.tag }}" TAG="$(echo "${TAG}" | xargs)" VERSION="${TAG#v}" if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 258c22742..c738c7287 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -195,205 +195,6 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release edit ${{ github.ref_name }} --repo ${{ github.repository }} --draft=false --prerelease - packages: - needs: publish - runs-on: ubuntu-latest - env: - APP_NAME: dbx - PRODUCT_NAME: DBX - REPO_OWNER: t8y2 - steps: - - name: Extract version from tag - id: version - run: | - TAG="${GITHUB_REF_NAME}" - VERSION="${TAG#v}" - if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then - echo "::error::Tag '${TAG}' does not look like a semver version." - exit 1 - fi - echo "version=${VERSION}" >> "$GITHUB_OUTPUT" - echo "tag=${TAG}" >> "$GITHUB_OUTPUT" - - - name: Download release assets - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - mkdir -p artifacts - VERSION="${{ steps.version.outputs.version }}" - TAG="${{ steps.version.outputs.tag }}" - - ASSETS=( - "${PRODUCT_NAME}_${VERSION}_aarch64.dmg" - "${PRODUCT_NAME}_${VERSION}_x64.dmg" - "${PRODUCT_NAME}_${VERSION}_x64-setup.exe" - ) - - for ASSET in "${ASSETS[@]}"; do - echo "::group::Downloading ${ASSET}" - gh release download "${TAG}" \ - --repo "${{ github.repository }}" \ - --pattern "${ASSET}" \ - --dir artifacts \ - --clobber - echo "::endgroup::" - done - - ls -lh artifacts/ - - - name: Compute SHA256 hashes - id: hashes - run: | - VERSION="${{ steps.version.outputs.version }}" - - compute_hash() { - local file="$1" name="$2" - if [[ ! -f "${file}" ]]; then - echo "::error::Missing artifact: ${file}" - exit 1 - fi - local hash - hash=$(sha256sum "${file}" | cut -d ' ' -f 1) - echo "${name}=${hash}" >> "$GITHUB_OUTPUT" - echo " ${name}: ${hash}" - } - - echo "SHA256 hashes:" - compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_aarch64.dmg" "sha_dmg_arm64" - compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_x64.dmg" "sha_dmg_x64" - compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_x64-setup.exe" "sha_exe" - - - name: Publish Homebrew Cask - env: - TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }} - run: | - VERSION="${{ steps.version.outputs.version }}" - SHA_ARM64="${{ steps.hashes.outputs.sha_dmg_arm64 }}" - SHA_X64="${{ steps.hashes.outputs.sha_dmg_x64 }}" - - git clone --depth 1 \ - "https://x-access-token:${TAP_GITHUB_TOKEN}@github.com/${REPO_OWNER}/homebrew-tap.git" \ - homebrew-tap - cd homebrew-tap - mkdir -p Casks - - cat > Casks/dbx.rb <<'RUBY_EOF' - cask "dbx" do - version "__VERSION__" - - on_arm do - url "https://github.com/__OWNER__/__APP__/releases/download/v#{version}/__PRODUCT___#{version}_aarch64.dmg", - verified: "github.com/__OWNER__/__APP__/" - sha256 "__SHA_ARM64__" - end - - on_intel do - url "https://github.com/__OWNER__/__APP__/releases/download/v#{version}/__PRODUCT___#{version}_x64.dmg", - verified: "github.com/__OWNER__/__APP__/" - sha256 "__SHA_X64__" - end - - name "DBX" - desc "Open-source database management tool" - homepage "https://github.com/__OWNER__/__APP__" - - livecheck do - url :url - strategy :github_latest - end - - depends_on macos: ">= :big_sur" - - app "DBX.app" - - zap trash: [ - "~/Library/Application Support/com.dbx.app", - "~/Library/Caches/com.dbx.app", - "~/Library/Preferences/com.dbx.app.plist", - "~/Library/Logs/com.dbx.app", - ] - end - RUBY_EOF - - sed -i 's/^ //' Casks/dbx.rb - - sed -i "s/__VERSION__/${VERSION}/g" Casks/dbx.rb - sed -i "s/__OWNER__/${REPO_OWNER}/g" Casks/dbx.rb - sed -i "s/__APP__/${APP_NAME}/g" Casks/dbx.rb - sed -i "s/__PRODUCT__/${PRODUCT_NAME}/g" Casks/dbx.rb - sed -i "s/__SHA_ARM64__/${SHA_ARM64}/g" Casks/dbx.rb - sed -i "s/__SHA_X64__/${SHA_X64}/g" Casks/dbx.rb - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add Casks/dbx.rb - - if git diff --cached --quiet; then - echo "Homebrew Cask is already up to date." - else - git commit -m "dbx ${VERSION}" - git push - echo "::notice::Homebrew Cask updated to ${VERSION}" - fi - - - name: Publish Scoop manifest - env: - TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }} - run: | - VERSION="${{ steps.version.outputs.version }}" - SHA_EXE="${{ steps.hashes.outputs.sha_exe }}" - - git clone --depth 1 \ - "https://x-access-token:${TAP_GITHUB_TOKEN}@github.com/${REPO_OWNER}/scoop-bucket.git" \ - scoop-bucket - cd scoop-bucket - - cat > dbx.json <) -> ConnectionConfig { ConnectionConfig { @@ -445,6 +448,13 @@ mod tests { } } + async fn test_app_state() -> (AppState, std::path::PathBuf) { + let dir = std::env::temp_dir().join(format!("dbx-core-test-{}", uuid::Uuid::new_v4())); + std::fs::create_dir_all(&dir).unwrap(); + let storage = Storage::open(&dir.join("storage.db")).await.unwrap(); + (AppState::new(storage), dir) + } + #[test] fn mysql_metadata_connection_ignores_saved_default_database() { let config = mysql_config(Some("app")); @@ -483,4 +493,28 @@ mod tests { assert_eq!(scoped.database.as_deref(), Some("ORCL")); } + + #[tokio::test] + async fn sqlite_get_or_create_pool_initializes_connection_for_web_route() { + let (state, dir) = test_app_state().await; + let db_path = dir.join("app.db"); + std::fs::File::create(&db_path).unwrap(); + let mut config = mysql_config(None); + config.id = "sqlite-conn".to_string(); + config.name = "SQLite".to_string(); + config.db_type = DatabaseType::Sqlite; + config.host = db_path.to_string_lossy().to_string(); + config.port = 0; + + state.configs.lock().await.insert(config.id.clone(), config); + + let pool_key = state.get_or_create_pool("sqlite-conn", None).await.unwrap(); + assert_eq!(pool_key, "sqlite-conn"); + + let databases = schema::list_databases_core(&state, "sqlite-conn").await.unwrap(); + assert_eq!(databases.len(), 1); + assert_eq!(databases[0].name, "main"); + + let _ = std::fs::remove_dir_all(dir); + } }