You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by li...@apache.org on 2022/12/20 00:53:43 UTC

[arrow-adbc] branch main updated: chore: add support for Debian and Ubuntu packages (#249)

This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new 14bbc3b  chore: add support for Debian and Ubuntu packages (#249)
14bbc3b is described below

commit 14bbc3b4ef549709a09792e0ff076cd58dd9a7ef
Author: Sutou Kouhei <ko...@clear-code.com>
AuthorDate: Tue Dec 20 09:53:22 2022 +0900

    chore: add support for Debian and Ubuntu packages (#249)
---
 .../{packaging-wheels.yml => packaging.yml}        | 106 +++++++-
 .gitignore                                         |  10 +
 ci/linux-packages/Rakefile                         | 272 +++++++++++++++++++++
 ci/linux-packages/apt/debian-bookworm/Dockerfile   |  63 +++++
 ci/linux-packages/apt/debian-bullseye/Dockerfile   |  63 +++++
 ci/linux-packages/apt/ubuntu-jammy/Dockerfile      |  61 +++++
 ci/linux-packages/debian/changelog                 |   0
 ci/linux-packages/debian/control                   | 151 ++++++++++++
 ci/linux-packages/debian/gir1.2-adbc-1.0.install   |   1 +
 .../debian/libadbc-driver-manager-dev.install      |   6 +
 .../debian/libadbc-driver-manager100.install       |   1 +
 .../debian/libadbc-driver-postgresql-dev.install   |   4 +
 .../debian/libadbc-driver-postgresql100.install    |   1 +
 .../debian/libadbc-driver-sqlite-dev.install       |   4 +
 .../debian/libadbc-driver-sqlite100.install        |   1 +
 ci/linux-packages/debian/libadbc-glib-dev.install  |   4 +
 ci/linux-packages/debian/libadbc-glib-doc.install  |   1 +
 ci/linux-packages/debian/libadbc-glib1.install     |   1 +
 ci/linux-packages/debian/rules                     |  92 +++++++
 dev/release/03-binary-sign.sh                      |   2 +-
 dev/release/rat_exclude_files.txt                  |   2 +
 dev/release/verify-apt.sh                          | 171 +++++++++++++
 glib/meson.build                                   |  15 +-
 23 files changed, 1024 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/packaging-wheels.yml b/.github/workflows/packaging.yml
similarity index 82%
rename from .github/workflows/packaging-wheels.yml
rename to .github/workflows/packaging.yml
index 4df8682..5526580 100644
--- a/.github/workflows/packaging-wheels.yml
+++ b/.github/workflows/packaging.yml
@@ -15,7 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-name: Packaging - Nightly Artifacts
+name: Packaging
 
 on:
   push:
@@ -122,6 +122,109 @@ jobs:
         env:
           GEMFURY_PUSH_TOKEN: ${{ secrets.GEMFURY_PUSH_TOKEN }}
 
+  linux:
+    name: Linux ${{ matrix.target }}
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        target:
+          - debian-bookworm
+          - debian-bullseye
+          - ubuntu-jammy
+    steps:
+      - uses: actions/checkout@v3
+
+      - uses: actions/checkout@v3
+        with:
+          repository: apache/arrow
+          path: arrow
+
+      - name: Set environment variables
+        run: |
+          echo "ARROW_SOURCE=$(pwd)/arrow" >> $GITHUB_ENV
+          case ${{ matrix.target }} in
+            debian-*|ubuntu-*)
+              echo "TASK_NAMESPACE=apt" >> $GITHUB_ENV
+              echo "APT_TARGETS=${{ matrix.target }}" >> $GITHUB_ENV
+              ;;
+          esac
+          distribution=$(echo ${{ matrix.target }} | cut -d- -f1)
+          echo "DISTRIBUTION=${distribution}" >> $GITHUB_ENV
+
+      - name: Set up Ruby
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ruby
+
+      - name: Cache ccache
+        uses: actions/cache@v3
+        with:
+          path: ci/linux-packages/${{ env.TASK_NAMESPACE }}/build/${{ matrix.target }}/ccache
+          key: linux-${{ env.TASK_NAMESPACE }}-ccache-${{ matrix.target }}-{{ "${{ hashFiles('adbc.h', 'c/**', 'glib/**') }}" }}
+          restore-keys: linux-${{ env.TASK_NAMESPACE }}-ccache-${{ matrix.target }}-
+
+      - name: Login to GitHub Container registry
+        uses: docker/login-action@v2
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ github.token }}
+
+      - name: Build
+        run: |
+          pushd ci/linux-packages
+          rake version:update
+          rake docker:pull || :
+          rake --trace ${TASK_NAMESPACE}:build BUILD_DIR=build
+          popd
+
+      - name: Prepare artifacts
+        run: |
+          cp -a \
+            ci/linux-packages/${{ env.TASK_NAMESPACE }}/repositories/${DISTRIBUTION} \
+            ./
+          tar czf ${{ matrix.target }}.tar.gz ${DISTRIBUTION}
+
+      - name: Upload artifacts
+        uses: actions/upload-artifact@v3
+        with:
+          name: ${{ matrix.target }}
+          path: |
+            ${{ matrix.target }}.tar.gz
+
+      - name: Push Docker image
+        run: |
+          pushd ci/linux-packages
+          rake docker:push || :
+          popd
+
+      - name: Set up test
+        run: |
+          sudo apt update
+          sudo apt install -y \
+            apt-utils \
+            createrepo-c \
+            devscripts \
+            gpg \
+            rpm
+          gem install apt-dists-merge
+          (echo "Key-Type: RSA"; \
+           echo "Key-Length: 4096"; \
+           echo "Name-Real: Test"; \
+           echo "Name-Email: test@example.com"; \
+           echo "%no-protection") | \
+            gpg --full-generate-key --batch
+          GPG_KEY_ID=$(gpg --list-keys --with-colon test@example.com | grep fpr | cut -d: -f10)
+          echo "GPG_KEY_ID=${GPG_KEY_ID}" >> ${GITHUB_ENV}
+          gpg --export --armor test@example.com > ci/linux-packages/KEYS
+
+      - name: Test
+        run: |
+          pushd ci/linux-packages
+          rake --trace ${TASK_NAMESPACE}:test
+          popd
+
   python-manylinux:
     name: "Python ${{ matrix.arch }} manylinux${{ matrix.manylinux_version }}"
     runs-on: ubuntu-latest
@@ -441,6 +544,7 @@ jobs:
     needs:
       - docs
       - java
+      - linux
       - python-manylinux
       - python-macos
       - python-windows
diff --git a/.gitignore b/.gitignore
index d09ff82..ffbc917 100644
--- a/.gitignore
+++ b/.gitignore
@@ -106,3 +106,13 @@ java-native-cpp/
 target/
 
 *.log
+
+# Linux packages
+/ci/linux-packages/*.tar.gz
+/ci/linux-packages/KEYS
+/ci/linux-packages/apt/build.sh
+/ci/linux-packages/apt/build/
+/ci/linux-packages/apt/env.sh
+/ci/linux-packages/apt/merged/
+/ci/linux-packages/apt/repositories/
+/ci/linux-packages/apt/tmp/
diff --git a/ci/linux-packages/Rakefile b/ci/linux-packages/Rakefile
new file mode 100644
index 0000000..7fcc272
--- /dev/null
+++ b/ci/linux-packages/Rakefile
@@ -0,0 +1,272 @@
+# -*- ruby -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+require "pathname"
+
+arrow_source = ENV["ARROW_SOURCE"]
+if arrow_source.nil?
+  raise "You must set ARROW_SOURCE environment variable"
+end
+ARROW_SOURCE = File.expand_path(arrow_source)
+require "#{ARROW_SOURCE}/dev/tasks/linux-packages/package-task"
+require "#{ARROW_SOURCE}/dev/release/binary-task"
+
+
+module Helper
+  private
+  def top_source_dir
+    Pathname(__dir__).parent.parent
+  end
+
+  def detect_version(release_time)
+    version_env = ENV["VERSION"]
+    return version_env if version_env
+
+    meson_build = top_source_dir / "c" / "cmake_modules" / "AdbcDefines.cmake"
+    version = meson_build.read.scan(/ADBC_VERSION "(.+?)"/)[0][0]
+    formatted_release_time = release_time.strftime("%Y%m%d")
+    version.gsub(/-SNAPSHOT\z/) {"-dev#{formatted_release_time}"}
+  end
+
+  def detect_release_time
+    release_time_env = ENV["RELEASE_TIME"]
+    if release_time_env
+      Time.parse(release_time_env).utc
+    else
+      Time.now.utc
+    end
+  end
+end
+
+class ADBCPackageTask < PackageTask
+  include Helper
+
+  def initialize
+    release_time = detect_release_time
+    super("apache-arrow-adbc", detect_version(release_time), release_time)
+  end
+
+  def define
+    super
+    define_rc_tasks
+    define_release_tasks
+  end
+
+  private
+  def define_archive_task
+    file @archive_name do
+      case @version
+      when /\A\d+\.\d+\.\d+-rc\d+\z/
+        download_rc_archive
+      when /\A\d+\.\d+\.\d+\z/
+        download_released_archive
+      else
+        build_archive
+      end
+    end
+
+    if deb_archive_name != @archive_name
+      file deb_archive_name => @archive_name do
+        cp(@archive_name, deb_archive_name)
+      end
+    end
+
+    if rpm_archive_name != @archive_name
+      file rpm_archive_name => @archive_name do
+        cp(@archive_name, rpm_archive_name)
+      end
+    end
+  end
+
+  def download_rc_archive
+    base_url = "https://dist.apache.org/repos/dist/dev/arrow"
+    archive_name_no_rc = @archive_name.gsub(/-rc\d+(\.tar\.gz)\z/, "\\1")
+    url = "#{base_url}/#{@package}-#{@version}/#{archive_name_no_rc}"
+    download(url, @archive_name)
+  end
+
+  def download_release_archive
+    base_url = "https://www.apache.org/dyn/closer.lua/arrow"
+    archive_name_no_rc = @archive_name.gsub(/-rc\d+(\.tar\.gz)\z/, "\\1")
+    url = "#{base_url}/#{@package}-#{@version}/#{archive_name_no_rc}"
+    url += "?action=download"
+    download(url, @archive_name)
+  end
+
+  def build_archive
+    cd(top_source_dir) do
+      sh("git",
+         "archive",
+         "HEAD",
+         "--output", @full_archive_name,
+         "--prefix", "#{@archive_base_name}/")
+    end
+  end
+
+  def apt_targets_default
+    [
+      "debian-bullseye",
+      # "debian-bullseye-arm64",
+      "debian-bookworm",
+      # "debian-bookworm-arm64",
+      "ubuntu-jammy",
+      # "ubuntu-jammy-arm64",
+    ]
+  end
+
+  def yum_targets_default
+    [
+      "almalinux-8",
+      # "almalinux-8-aarch64",
+      "almalinux-9",
+      # "almalinux-9-aarch64",
+    ]
+  end
+
+  def github_repository
+    ENV["GITHUB_REPOSITORY"] || "apache/arrow-adbc"
+  end
+
+  def docker_image(os, architecture)
+    "ghcr.io/#{github_repository}/package-#{super}"
+  end
+
+  def built_package_url(target_namespace, target)
+    url = "https://github.com/#{github_repository}"
+    url << "/releases/download/#{@version}/"
+    case target_namespace
+    when :apt
+      if target.end_with?("-arm64")
+        url << "#{target}.tar.gz"
+      else
+        url << "#{target}-amd64.tar.gz"
+      end
+    when :yum
+      if target.end_with?("-aarch64")
+        url << "#{target}.tar.gz"
+      else
+        url << "#{target}-x86_64.tar.gz"
+      end
+    end
+    url
+  end
+
+  def package_dir_name
+    "#{@package}-#{@version}"
+  end
+
+  def download_packages(target_namespace)
+    download_dir = "#{ARROW_SOURCE}/packages/#{package_dir_name}"
+    mkdir_p(download_dir)
+    __send__("#{target_namespace}_targets").each do |target|
+      url = built_package_url(target_namespace, target)
+      archive = download(url, download_dir)
+      cd(download_dir) do
+        sh("tar", "xf", archive)
+      end
+    end
+  end
+
+  def upload_rc(target_namespace)
+    targets = __send__("#{target_namespace}_targets")
+    cd(apache_arrow_dir) do
+      env = {
+        "CROSSBOW_JOB_ID" => package_dir_name,
+        "DEB_PACKAGE_NAME" => @package,
+        "STAGING" => ENV["STAGING"] || "no",
+        "UPLOAD_DEFAULT" => "0",
+      }
+      targets.each do |target|
+        distribution = target.split("-")[0].upcase
+        env["UPLOAD_#{distribution}"] = "1"
+      end
+      sh(env,
+         "dev/release/05-binary-upload.sh",
+         @version,
+         "0")
+    end
+  end
+
+  def define_rc_tasks
+    [:apt, :yum].each do |target_namespace|
+      tasks = []
+      namespace target_namespace do
+        desc "Upload RC #{target_namespace} packages"
+        task :rc do
+          download_packages(target_namespace)
+          upload_rc(target_namespace)
+        end
+        tasks << "#{target_namespace}:release"
+      end
+      task target_namespace => tasks
+    end
+  end
+
+  def release(target_namespace)
+    targets = __send__("#{target_namespace}_targets")
+    cd(apache_arrow_dir) do
+      env = {
+        "STAGING" => ENV["STAGING"] || "no",
+        "DEPLOY_DEFAULT" => "0",
+      }
+      targets.each do |target|
+        distribution = target.split("-")[0].upcase
+        env["DEPLOY_#{distribution}"] = "1"
+      end
+      sh(env,
+         "dev/release/post-02-binary.sh",
+         @version,
+         "0")
+    end
+  end
+
+  def define_release_tasks
+    [:apt, :yum].each do |target_namespace|
+      tasks = []
+      namespace target_namespace do
+        desc "Release #{target_namespace} packages"
+        task :release do
+          release(target_namespace)
+        end
+        tasks << "#{target_namespace}:release"
+      end
+      task target_namespace => tasks
+    end
+  end
+
+  def enable_yum?
+    false
+  end
+end
+
+class ADBCLocalBinaryTask < LocalBinaryTask
+  include Helper
+
+  def initialize
+    super([], top_source_dir.expand_path)
+  end
+
+  private
+  def version
+    @version ||= detect_version(detect_release_time)
+  end
+end
+
+ADBCPackageTask.new.define
+ADBCLocalBinaryTask.new.define
diff --git a/ci/linux-packages/apt/debian-bookworm/Dockerfile b/ci/linux-packages/apt/debian-bookworm/Dockerfile
new file mode 100644
index 0000000..289228f
--- /dev/null
+++ b/ci/linux-packages/apt/debian-bookworm/Dockerfile
@@ -0,0 +1,63 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+ARG FROM=debian:bookworm
+FROM ${FROM}
+
+RUN \
+  echo "debconf debconf/frontend select Noninteractive" | \
+    debconf-set-selections
+
+RUN \
+  echo 'APT::Install-Recommends "false";' > \
+    /etc/apt/apt.conf.d/disable-install-recommends
+
+RUN sed -i'' -e 's/main$/main contrib non-free/g' /etc/apt/sources.list
+
+ARG DEBUG
+RUN \
+  quiet=$([ "${DEBUG}" = "yes" ] || echo "-qq") && \
+  apt update ${quiet} && \
+  apt install -y -V ${quiet} \
+    ca-certificates \
+    lsb-release \
+    wget && \
+  wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  apt install -y -V ${quiet} \
+    ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  rm apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  apt update && \
+  apt install -y -V ${quiet} \
+    build-essential \
+    ccache \
+    cmake \
+    debhelper \
+    devscripts \
+    gobject-introspection \
+    libarrow-glib-dev \
+    libgirepository1.0-dev \
+    libpq-dev \
+    libsqlite3-dev \
+    ninja-build \
+    pkg-config \
+    python3-dev \
+    python3-pip \
+    tzdata \
+    valac && \
+  pip3 install --upgrade meson && \
+  ln -s /usr/local/bin/meson /usr/bin/ && \
+  apt clean
diff --git a/ci/linux-packages/apt/debian-bullseye/Dockerfile b/ci/linux-packages/apt/debian-bullseye/Dockerfile
new file mode 100644
index 0000000..d26e20f
--- /dev/null
+++ b/ci/linux-packages/apt/debian-bullseye/Dockerfile
@@ -0,0 +1,63 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+ARG FROM=debian:bullseye
+FROM ${FROM}
+
+RUN \
+  echo "debconf debconf/frontend select Noninteractive" | \
+    debconf-set-selections
+
+RUN \
+  echo 'APT::Install-Recommends "false";' > \
+    /etc/apt/apt.conf.d/disable-install-recommends
+
+RUN sed -i'' -e 's/main$/main contrib non-free/g' /etc/apt/sources.list
+
+ARG DEBUG
+RUN \
+  quiet=$([ "${DEBUG}" = "yes" ] || echo "-qq") && \
+  apt update ${quiet} && \
+  apt install -y -V ${quiet} \
+    ca-certificates \
+    lsb-release \
+    wget && \
+  wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  apt install -y -V ${quiet} \
+    ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  rm apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  apt update && \
+  apt install -y -V ${quiet} \
+    build-essential \
+    ccache \
+    cmake \
+    debhelper \
+    devscripts \
+    gobject-introspection \
+    libarrow-glib-dev \
+    libgirepository1.0-dev \
+    libpq-dev \
+    libsqlite3-dev \
+    ninja-build \
+    pkg-config \
+    python3-dev \
+    python3-pip \
+    tzdata \
+    valac && \
+  pip3 install --upgrade meson && \
+  ln -s /usr/local/bin/meson /usr/bin/ && \
+  apt clean
diff --git a/ci/linux-packages/apt/ubuntu-jammy/Dockerfile b/ci/linux-packages/apt/ubuntu-jammy/Dockerfile
new file mode 100644
index 0000000..82d4e78
--- /dev/null
+++ b/ci/linux-packages/apt/ubuntu-jammy/Dockerfile
@@ -0,0 +1,61 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+ARG FROM=ubuntu:jammy
+FROM ${FROM}
+
+RUN \
+  echo "debconf debconf/frontend select Noninteractive" | \
+    debconf-set-selections
+
+RUN \
+  echo 'APT::Install-Recommends "false";' > \
+    /etc/apt/apt.conf.d/disable-install-recommends
+
+ARG DEBUG
+RUN \
+  quiet=$([ "${DEBUG}" = "yes" ] || echo "-qq") && \
+  apt update ${quiet} && \
+  apt install -y -V ${quiet} \
+    ca-certificates \
+    lsb-release \
+    wget && \
+  wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  apt install -y -V ${quiet} \
+    ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  rm apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
+  apt update && \
+  apt install -y -V ${quiet} \
+    build-essential \
+    ccache \
+    cmake \
+    debhelper \
+    devscripts \
+    gobject-introspection \
+    libarrow-glib-dev \
+    libgirepository1.0-dev \
+    libpq-dev \
+    libsqlite3-dev \
+    ninja-build \
+    pkg-config \
+    python3-dev \
+    python3-pip \
+    tzdata \
+    valac && \
+  pip3 install --upgrade meson && \
+  ln -s /usr/local/bin/meson /usr/bin/ && \
+  apt clean
diff --git a/ci/linux-packages/debian/changelog b/ci/linux-packages/debian/changelog
new file mode 100644
index 0000000..e69de29
diff --git a/ci/linux-packages/debian/control b/ci/linux-packages/debian/control
new file mode 100644
index 0000000..43e21e9
--- /dev/null
+++ b/ci/linux-packages/debian/control
@@ -0,0 +1,151 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+Source: apache-arrow-adbc
+Section: devel
+Priority: optional
+Maintainer: Apache Arrow Developers <de...@arrow.apache.org>
+Build-Depends:
+  cmake,
+  debhelper-compat (= 12),
+  gobject-introspection,
+  libgirepository1.0-dev,
+  libpq-dev,
+  libsqlite3-dev,
+  tzdata,
+  valac
+Standards-Version: 4.5.0
+Homepage: https://arrow.apache.org/adbc/
+
+Package: libadbc-driver-manager100
+Section: libs
+Architecture: any
+Multi-Arch: same
+Pre-Depends: ${misc:Pre-Depends}
+Depends:
+  ${misc:Depends},
+  ${shlibs:Depends}
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides C++ library files.
+
+Package: libadbc-driver-manager-dev
+Section: libdevel
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${misc:Depends},
+  libadbc-driver-manager100 (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides C++ header files.
+
+Package: libadbc-driver-postgresql100
+Section: libs
+Architecture: any
+Multi-Arch: same
+Pre-Depends: ${misc:Pre-Depends}
+Depends:
+  ${misc:Depends},
+  ${shlibs:Depends}
+Description: Apache Arrow Database Connectivity (ADBC) PostgreSQL driver
+ .
+ This package provides an ADBC driver for PostgreSQL
+
+Package: libadbc-driver-postgresql-dev
+Section: libdevel
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${misc:Depends},
+  libadbc-driver-postgresql100 (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) PostgreSQL driver
+ .
+ This package provides CMake package, pkg-config package and so on.
+
+Package: libadbc-driver-sqlite100
+Section: libs
+Architecture: any
+Multi-Arch: same
+Pre-Depends: ${misc:Pre-Depends}
+Depends:
+  ${misc:Depends},
+  ${shlibs:Depends}
+Description: Apache Arrow Database Connectivity (ADBC) PostgreSQL driver
+ .
+ This package provides an ADBC driver for PostgreSQL
+
+Package: libadbc-driver-sqlite-dev
+Section: libdevel
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${misc:Depends},
+  libadbc-driver-sqlite100 (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) SQLite driver
+ .
+ This package provides CMake package, pkg-config package and so on.
+
+Package: libadbc-glib1
+Section: libs
+Architecture: any
+Multi-Arch: same
+Pre-Depends: ${misc:Pre-Depends}
+Depends:
+  ${misc:Depends},
+  ${shlibs:Depends},
+  libadbc-driver-manager100 (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides GLib based library files.
+
+Package: gir1.2-adbc-1.0
+Section: introspection
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${gir:Depends},
+  ${misc:Depends}
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides GObject Introspection typelib files.
+
+Package: libadbc-glib-dev
+Section: libdevel
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${misc:Depends},
+  gir1.2-adbc-1.0 (= ${binary:Version}),
+  libadbc-driver-manager-dev (= ${binary:Version}),
+  libarrow-glib-dev
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides GLib based header files.
+
+Package: libadbc-glib-doc
+Section: doc
+Architecture: all
+Multi-Arch: foreign
+Depends:
+  ${misc:Depends}
+Recommends:
+  libglib2.0-doc,
+  libarrow-glib-doc
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides documentations.
diff --git a/ci/linux-packages/debian/gir1.2-adbc-1.0.install b/ci/linux-packages/debian/gir1.2-adbc-1.0.install
new file mode 100644
index 0000000..0c3f40f
--- /dev/null
+++ b/ci/linux-packages/debian/gir1.2-adbc-1.0.install
@@ -0,0 +1 @@
+usr/lib/*/girepository-1.0/ADBC-*.typelib
diff --git a/ci/linux-packages/debian/libadbc-driver-manager-dev.install b/ci/linux-packages/debian/libadbc-driver-manager-dev.install
new file mode 100644
index 0000000..6cee53d
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-driver-manager-dev.install
@@ -0,0 +1,6 @@
+usr/include/adbc.h
+usr/include/adbc_driver_manager.h
+usr/lib/*/cmake/AdbcDriverManager/
+usr/lib/*/libadbc_driver_manager.a
+usr/lib/*/libadbc_driver_manager.so
+usr/lib/*/pkgconfig/adbc-driver-manager.pc
diff --git a/ci/linux-packages/debian/libadbc-driver-manager100.install b/ci/linux-packages/debian/libadbc-driver-manager100.install
new file mode 100644
index 0000000..0dc76b6
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-driver-manager100.install
@@ -0,0 +1 @@
+usr/lib/*/libadbc_driver_manager.so.*
diff --git a/ci/linux-packages/debian/libadbc-driver-postgresql-dev.install b/ci/linux-packages/debian/libadbc-driver-postgresql-dev.install
new file mode 100644
index 0000000..9f88326
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-driver-postgresql-dev.install
@@ -0,0 +1,4 @@
+usr/lib/*/cmake/AdbcDriverPostgreSQL/
+usr/lib/*/libadbc_driver_postgresql.a
+usr/lib/*/libadbc_driver_postgresql.so
+usr/lib/*/pkgconfig/adbc-driver-postgresql.pc
diff --git a/ci/linux-packages/debian/libadbc-driver-postgresql100.install b/ci/linux-packages/debian/libadbc-driver-postgresql100.install
new file mode 100644
index 0000000..3466dc6
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-driver-postgresql100.install
@@ -0,0 +1 @@
+usr/lib/*/libadbc_driver_postgresql.so.*
diff --git a/ci/linux-packages/debian/libadbc-driver-sqlite-dev.install b/ci/linux-packages/debian/libadbc-driver-sqlite-dev.install
new file mode 100644
index 0000000..fca0a93
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-driver-sqlite-dev.install
@@ -0,0 +1,4 @@
+usr/lib/*/cmake/AdbcDriverSQLite/
+usr/lib/*/libadbc_driver_sqlite.a
+usr/lib/*/libadbc_driver_sqlite.so
+usr/lib/*/pkgconfig/adbc-driver-sqlite.pc
diff --git a/ci/linux-packages/debian/libadbc-driver-sqlite100.install b/ci/linux-packages/debian/libadbc-driver-sqlite100.install
new file mode 100644
index 0000000..a60e19f
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-driver-sqlite100.install
@@ -0,0 +1 @@
+usr/lib/*/libadbc_driver_sqlite.so.*
diff --git a/ci/linux-packages/debian/libadbc-glib-dev.install b/ci/linux-packages/debian/libadbc-glib-dev.install
new file mode 100644
index 0000000..d8b552a
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-glib-dev.install
@@ -0,0 +1,4 @@
+usr/include/adbc-glib/
+usr/lib/*/libadbc-glib.so
+usr/lib/*/pkgconfig/adbc-glib.pc
+usr/share/gir-1.0/ADBC-*.gir
diff --git a/ci/linux-packages/debian/libadbc-glib-doc.install b/ci/linux-packages/debian/libadbc-glib-doc.install
new file mode 100644
index 0000000..5c384b8
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-glib-doc.install
@@ -0,0 +1 @@
+usr/share/doc/adbc-glib/
diff --git a/ci/linux-packages/debian/libadbc-glib1.install b/ci/linux-packages/debian/libadbc-glib1.install
new file mode 100644
index 0000000..98c688b
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-glib1.install
@@ -0,0 +1 @@
+usr/lib/*/libadbc-glib.so.*
diff --git a/ci/linux-packages/debian/rules b/ci/linux-packages/debian/rules
new file mode 100755
index 0000000..338edcc
--- /dev/null
+++ b/ci/linux-packages/debian/rules
@@ -0,0 +1,92 @@
+#!/usr/bin/make -f
+# -*- makefile-gmake -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+# This has to be exported to make some magic below work.
+export DH_OPTIONS
+
+export DEB_BUILD_MAINT_OPTIONS=reproducible=-timeless
+
+%:
+	dh $@ --with gir
+
+CMAKE_BUILD_TYPE = RelWithDebInfo
+
+override_dh_auto_configure:
+	dh_auto_configure				\
+	  --sourcedirectory=c/driver_manager		\
+	  --builddirectory=c/driver_manager.build	\
+	  --buildsystem=cmake+ninja			\
+	  --						\
+	  -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE)
+	dh_auto_configure				\
+	  --sourcedirectory=c/driver/postgresql		\
+	  --builddirectory=c/driver/postgresql.build	\
+	  --buildsystem=cmake+ninja			\
+	  --						\
+	  -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE)
+	dh_auto_configure				\
+	  --sourcedirectory=c/driver/sqlite		\
+	  --builddirectory=c/driver/sqlite.build	\
+	  --buildsystem=cmake+ninja			\
+	  --						\
+	  -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE)
+
+override_dh_auto_build:
+	dh_auto_build					\
+	  --sourcedirectory=c/driver_manager		\
+	  --builddirectory=c/driver_manager.build
+	dh_auto_build					\
+	  --sourcedirectory=c/driver/postgresql		\
+	  --builddirectory=c/driver/postgresql.build
+	dh_auto_build					\
+	  --sourcedirectory=c/driver/sqlite		\
+	  --builddirectory=c/driver/sqlite.build
+	dh_auto_configure				\
+	  --sourcedirectory=glib			\
+	  --builddirectory=glib.build			\
+	  --buildsystem=meson+ninja			\
+	  --						\
+	  --buildtype=debugoptimized			\
+	  -Dadbc_build_dir=../c/driver_manager.build
+	env							\
+	  LD_LIBRARY_PATH=$(CURDIR)/c/driver_manager.build	\
+	    dh_auto_build					\
+	      --sourcedirectory=glib				\
+	      --builddirectory=glib.build			\
+	      --buildsystem=meson+ninja
+
+override_dh_auto_install:
+	dh_auto_install					\
+	  --sourcedirectory=c/driver_manager		\
+	  --builddirectory=c/driver_manager.build
+	dh_auto_install					\
+	  --sourcedirectory=c/driver/postgresql		\
+	  --builddirectory=c/driver/postgresql.build
+	dh_auto_install					\
+	  --sourcedirectory=c/driver/sqlite		\
+	  --builddirectory=c/driver/sqlite.build
+	dh_auto_install				\
+	   --sourcedirectory=glib		\
+	   --builddirectory=glib.build		\
+	   --buildsystem=meson+ninja
+
+override_dh_auto_test:
diff --git a/dev/release/03-binary-sign.sh b/dev/release/03-binary-sign.sh
index 5d5f283..cae49c1 100755
--- a/dev/release/03-binary-sign.sh
+++ b/dev/release/03-binary-sign.sh
@@ -48,7 +48,7 @@ main() {
         echo "Waiting for run to start..."
         run_id=$(gh run list \
                     --repo "${REPOSITORY}" \
-                    --workflow=packaging-wheels.yml \
+                    --workflow=packaging.yml \
                     --json 'databaseId,event,headBranch,status' \
                     --jq ".[] | select(.event == \"push\" and .headBranch == \"${tag}\") | .databaseId")
         sleep 1
diff --git a/dev/release/rat_exclude_files.txt b/dev/release/rat_exclude_files.txt
index 1024579..40bb06b 100644
--- a/dev/release/rat_exclude_files.txt
+++ b/dev/release/rat_exclude_files.txt
@@ -1,4 +1,6 @@
 *.json
+ci/linux-packages/changelog
+ci/linux-packages/*.install
 dev/release/rat_exclude_files.txt
 go/adbc/status_string.go
 go/adbc/go.sum
diff --git a/dev/release/verify-apt.sh b/dev/release/verify-apt.sh
new file mode 100755
index 0000000..7711be0
--- /dev/null
+++ b/dev/release/verify-apt.sh
@@ -0,0 +1,171 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -exu
+
+if [ $# -lt 2 ]; then
+  echo "Usage: $0 VERSION rc"
+  echo "       $0 VERSION staging-rc"
+  echo "       $0 VERSION release"
+  echo "       $0 VERSION staging-release"
+  echo "       $0 VERSION local"
+  echo " e.g.: $0 1.0.0 rc                # Verify 1.0.0 RC"
+  echo " e.g.: $0 1.0.0 staging-rc        # Verify 1.0.0 RC on staging"
+  echo " e.g.: $0 1.0.0 release           # Verify 1.0.0"
+  echo " e.g.: $0 1.0.0 staging-release   # Verify 1.0.0 on staging"
+  echo " e.g.: $0 1.0.0-dev20210203 local # Verify 1.0.0-dev20210203 on local"
+  exit 1
+fi
+
+VERSION="$1"
+TYPE="$2"
+
+SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+local_prefix="${SOURCE_DIR}/../../ci/linux-packages"
+
+
+echo "::group::Prepare repository"
+
+export DEBIAN_FRONTEND=noninteractive
+
+APT_INSTALL="apt install -y -V --no-install-recommends"
+
+apt update
+${APT_INSTALL} \
+  ca-certificates \
+  curl \
+  lsb-release
+
+code_name="$(lsb_release --codename --short)"
+distribution="$(lsb_release --id --short | tr 'A-Z' 'a-z')"
+artifactory_base_url="https://apache.jfrog.io/artifactory/arrow/${distribution}"
+case "${TYPE}" in
+  rc|staging-rc|staging-release)
+    suffix=${TYPE%-release}
+    artifactory_base_url+="-${suffix}"
+    ;;
+esac
+
+case "${distribution}-${code_name}" in
+  debian-*)
+    sed \
+      -i"" \
+      -e "s/ main$/ main contrib non-free/g" \
+      /etc/apt/sources.list
+    ;;
+esac
+
+curl \
+    --fail \
+    --location \
+    --remote-name \
+     https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
+${APT_INSTALL} ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
+
+if [ "${TYPE}" = "local" ]; then
+  case "${VERSION}" in
+    *-dev*)
+      package_version="$(echo "${VERSION}" | sed -e 's/-dev\(.*\)$/~dev\1/g')"
+      ;;
+    *-rc*)
+      package_version="$(echo "${VERSION}" | sed -e 's/-rc.*$//g')"
+      ;;
+    *)
+      package_version="${VERSION}"
+      ;;
+  esac
+  package_version+="-1"
+else
+  package_version="${VERSION}-1"
+fi
+
+if [ "${TYPE}" = "local" ]; then
+  sed \
+    -e "s,^URIs: .*$,URIs: file://${local_prefix}/apt/repositories/${distribution},g" \
+    -e "s,^Signed-By: .*$,Signed-By: /usr/share/keyrings/apache-arrow-adbc-apt-source.gpg,g" \
+    /etc/apt/sources.list.d/apache-arrow.sources > \
+    /etc/apt/sources.list.d/apache-arrow-adbc.sources
+  keys="${local_prefix}/KEYS"
+  if [ -f "${keys}" ]; then
+    gpg \
+      --no-default-keyring \
+      --keyring /usr/share/keyrings/apache-arrow-adbc-apt-source.gpg \
+      --import "${keys}"
+  fi
+else
+  case "${TYPE}" in
+    rc|staging-rc|staging-release)
+      suffix=${TYPE%-release}
+      sed \
+        -i"" \
+        -e "s,^URIs: \\(.*\\)/,URIs: \\1-${suffix}/,g" \
+        /etc/apt/sources.list.d/apache-arrow.sources
+      ;;
+  esac
+fi
+
+apt update
+
+echo "::endgroup::"
+
+
+echo "::group::Test ADBC Driver Manager"
+${APT_INSTALL} libadbc-driver-manager-dev=${package_version}
+required_packages=()
+required_packages+=(cmake)
+required_packages+=(gcc)
+required_packages+=(make)
+required_packages+=(pkg-config)
+${APT_INSTALL} ${required_packages[@]}
+# TODO
+# mkdir -p build
+# cp -a /adbc/c/driver_manager/example build/
+# pushd build/example
+# cmake .
+# make -j$(nproc)
+# ./adbc-driver-manager-example
+# cc \
+#   -o adbc-driver-manager \
+#   adbc-driver-manager.c \
+#   $(pkg-config --cflags --libs adbc-driver-manager)
+# ./adbc-driver-manager-example
+# popd
+echo "::endgroup::"
+
+
+echo "::group::Test ADBC PostgreSQL Driver"
+${APT_INSTALL} libadbc-driver-postgresql-dev=${package_version}
+echo "::endgroup::"
+
+
+echo "::group::Test ADBC SQLite Driver"
+${APT_INSTALL} libadbc-driver-sqlite-dev=${package_version}
+echo "::endgroup::"
+
+
+echo "::group::Test ADBC GLib"
+export G_DEBUG=fatal-warnings
+
+${APT_INSTALL} libadbc-glib-dev=${package_version}
+${APT_INSTALL} libadbc-glib-doc=${package_version}
+
+${APT_INSTALL} ruby-dev rubygems-integration
+gem install gobject-introspection
+ruby -r gi -e "p GI.load('ADBC')"
+echo "::endgroup::"
diff --git a/glib/meson.build b/glib/meson.build
index 93feef8..3f7e88b 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -45,7 +45,8 @@ pkgconfig = import('pkgconfig')
 pkgconfig_variables = ['girdir=@0@'.format(gir_dir)]
 
 base_include_directories = [
-  include_directories('.')
+  include_directories('.'),
+  include_directories('..'),
 ]
 
 gi_fatal_warnings = (build_machine.system() != 'windows')
@@ -72,8 +73,10 @@ install_data('../LICENSE.txt',
              'README.md',
              install_dir: data_dir / 'doc' / meson.project_name())
 
-ruby = find_program('ruby')
-test_run_rb = files('test/run.rb')
-test('unit test',
-     ruby,
-     args: [test_run_rb])
+ruby = find_program('ruby', required: false)
+if ruby.found()
+  test_run_rb = files('test/run.rb')
+  test('unit test',
+       ruby,
+       args: [test_run_rb])
+endif