Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
name: CI

on:
push:
branches:
- main
pull_request:
branches:
- main

env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
CARGO_INCREMENTAL: "false"

jobs:
Test:
strategy:
fail-fast: false # We want all of them to run, even if one fails
matrix:
os: [ "ubuntu-latest" ]
pg: [ "12", "13", "14", "15", "16" ]

runs-on: ${{ matrix.os }}
env:
RUSTC_WRAPPER: sccache
SCCACHE_DIR: /home/runner/.cache/sccache
RUST_TOOLCHAIN: ${{ matrix.rust || 'stable' }}
steps:
- uses: actions/checkout@v4
- name: Set up prerequisites and environment
run: |
sudo apt-get update -y -qq --fix-missing

echo ""
echo "----- Install sccache -----"
mkdir -p $HOME/.local/bin
curl -L https://github.com/mozilla/sccache/releases/download/v0.2.15/sccache-v0.2.15-x86_64-unknown-linux-musl.tar.gz | tar xz
mv -f sccache-v0.2.15-x86_64-unknown-linux-musl/sccache $HOME/.local/bin/sccache
chmod +x $HOME/.local/bin/sccache
echo "$HOME/.local/bin" >> $GITHUB_PATH
mkdir -p /home/runner/.cache/sccache
echo ""

echo "----- Set up dynamic variables -----"
cat $GITHUB_ENV
echo ""

echo "----- Install system dependencies -----"
sudo apt-get install -y \
build-essential \
llvm-14-dev libclang-14-dev clang-14 \
gcc \
libssl-dev \
libz-dev \
make \
pkg-config \
strace \
zlib1g-dev
echo ""
echo "----- Print env -----"
env
echo ""

- name: Install release version of PostgreSQL
run: |
echo "----- Set up PostgreSQL Apt repository -----"
sudo apt-get install -y wget gnupg
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update -y -qq --fix-missing
echo ""

sudo apt-get install -y \
postgresql-${{ matrix.pg }} \
postgresql-server-dev-${{ matrix.pg }}

echo ""
echo "----- pg_config -----"
pg_config
echo ""
- name: Set up PostgreSQL permissions
run: sudo chmod a+rwx `/usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config --pkglibdir` `/usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config --sharedir`/extension /var/run/postgresql/

- name: Cache cargo registry
uses: actions/cache@v4
continue-on-error: false
with:
path: |
~/.cargo/registry
~/.cargo/git
key: tests-${{ runner.os }}-${{ hashFiles('**/Cargo.lock', '.github/workflows/tests.yml') }}

- name: Cache sccache directory
uses: actions/cache@v4
continue-on-error: false
with:
path: /home/runner/.cache/sccache
key: pgrx-tests-sccache-${{ runner.os }}-${{ hashFiles('**/Cargo.lock', '.github/workflows/tests.yml') }}

- name: Start sccache server
run: sccache --start-server

- name: Print sccache stats (before run)
run: sccache --show-stats

- name: Install cargo-pgrx
run: |
PGRX_VERSION=$(cargo metadata --format-version 1 | jq -r '.packages[]|select(.name=="pgrx")|.version')
cargo install --locked --version=$PGRX_VERSION cargo-pgrx --debug --force
cargo pgrx init --pg${{ matrix.pg }} /usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config
- name: Run tests
run: echo "\q" | cargo pgrx run pg${{ matrix.pg }} && cargo test --no-default-features --features pg${{ matrix.pg }}

- name: Build
run: cargo pgrx package --features pg${{ matrix.pg }} --pg-config /usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config

- name: Archive production artifacts
uses: actions/upload-artifact@v4
with:
name: typeid-${{matrix.pg}}
path: |
target/release/typeid-pg${{ matrix.pg }}
# Attempt to make the cache payload slightly smaller.
- name: Clean up built PGRX files
run: |
cd target/debug/deps/
for built_file in $(find * -type f -executable -print | grep -v "\.so$"); do
base_name=$(echo $built_file | cut -d- -f1);
for basefile in "$base_name".*; do
[ -f "$basefile" ] || continue;
echo "Removing $basefile"
rm $basefile
done;
echo "Removing $built_file"
rm $built_file
done
- name: Stop sccache server
run: sccache --stop-server || true
Install:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install PostgreSQL headers
run: |
sudo apt-get update
sudo apt-get install postgresql-server-dev-14
- name: Install cargo-pgrx
run: |
PGRX_VERSION=$(cargo metadata --format-version 1 | jq -r '.packages[]|select(.name=="pgrx")|.version')
cargo install --locked --version=$PGRX_VERSION cargo-pgrx --debug --force
cargo pgrx init --pg14 $(which pg_config)
- name: Install TypeID/pgrx
run: |
cargo pgrx install --no-default-features --release --sudo
- name: Start PostgreSQL
run: |
sudo systemctl start postgresql.service
pg_isready
# superuser (-s), can create databases (-d) and roles (-r), no password prompt (-w) named runner
sudo -u postgres createuser -s -d -r -w runner
- name: Verify install
run: |
createdb -U runner runner
psql -U runner -c "create extension typeid;"
psql -U runner -c "select typeid_generate('user');"
rustfmt:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run rustfmt
run: cargo fmt -- --check
86 changes: 86 additions & 0 deletions .github/workflows/clippy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# rust-clippy is a tool that runs a bunch of lints to catch common
# mistakes in your Rust code and help improve your Rust code.
# More details at https://github.com/rust-lang/rust-clippy
# and https://rust-lang.github.io/rust-clippy/

name: rust-clippy analyze

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '20 14 * * 5'

jobs:
rust-clippy-analyze:
name: Run rust-clippy analyzing
runs-on: ubuntu-latest

strategy:
matrix:
pg: [ "16" ]
permissions:
contents: read
security-events: write
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af #@v1
with:
profile: minimal
toolchain: stable
components: clippy
override: true

- name: Install release version of PostgreSQL
run: |
echo "----- Set up PostgreSQL Apt repository -----"
sudo apt-get install -y wget gnupg
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update -y -qq --fix-missing
echo ""

sudo apt-get install -y \
postgresql-${{ matrix.pg }} \
postgresql-server-dev-${{ matrix.pg }}

echo ""
echo "----- pg_config -----"
pg_config
echo ""

- name: Set up PostgreSQL permissions
run: sudo chmod a+rwx `/usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config --pkglibdir` `/usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config --sharedir`/extension /var/run/postgresql/

- name: Install cargo-pgrx
run: |
PGRX_VERSION=$(cargo metadata --format-version 1 | jq -r '.packages[]|select(.name=="pgrx")|.version')
cargo install --locked --version=$PGRX_VERSION cargo-pgrx --debug --force
cargo pgrx init --pg${{ matrix.pg }} /usr/lib/postgresql/${{ matrix.pg }}/bin/pg_config

- name: Install required cargo
run: cargo install clippy-sarif sarif-fmt

- name: Run rust-clippy
run:
cargo clippy
--all-features
--message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt
continue-on-error: true

- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: rust-clippy-results.sarif
wait-for-processing: true
68 changes: 33 additions & 35 deletions src/base32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,59 +9,57 @@ pub enum Error {
}

fn decode_base32_to_u128(id: &str) -> Result<u128, Error> {
let mut id: [u8; 26] = id.as_bytes().try_into().map_err(|_| Error::InvalidData)?;
let mut max = 0;
for b in &mut id {
*b = CROCKFORD_INV[*b as usize];
max |= *b;
}
if max > 32 || id[0] > 7 {
return Err(Error::InvalidData);
}
let mut id: [u8; 26] = id.as_bytes().try_into().map_err(|_| Error::InvalidData)?;
let mut max = 0;
for b in &mut id {
*b = CROCKFORD_INV[*b as usize];
max |= *b;
}
if max > 32 || id[0] > 7 {
return Err(Error::InvalidData);
}

let mut out = 0u128;
for b in id {
out <<= 5;
out |= b as u128;
}
let mut out = 0u128;
for b in id {
out <<= 5;
out |= b as u128;
}

Ok(out)
Ok(out)
}

fn encode_u128_to_base32(data: u128) -> String {
let mut buf = [0u8; 26];
let mut data = data;
for i in (0..26).rev() {
buf[i] = CROCKFORD[(data & 0x1f) as usize];
debug_assert!(buf[i].is_ascii());
data >>= 5;
}
unsafe { String::from_utf8_unchecked(buf.to_vec()) }
let mut buf = [0u8; 26];
let mut data = data;
for i in (0..26).rev() {
buf[i] = CROCKFORD[(data & 0x1f) as usize];
debug_assert!(buf[i].is_ascii());
data >>= 5;
}
unsafe { String::from_utf8_unchecked(buf.to_vec()) }
}

const CROCKFORD: &[u8; 32] = b"0123456789abcdefghjkmnpqrstvwxyz";
const CROCKFORD_INV: &[u8; 256] = &{
let mut output = [255; 256];
let mut output = [255; 256];

let mut i = 0;
while i < 32 {
output[CROCKFORD[i as usize] as usize] = i;
i += 1;
}
let mut i = 0;
while i < 32 {
output[CROCKFORD[i as usize] as usize] = i;
i += 1;
}

output
output
};


pub fn encode_base32_uuid(uuid: &Uuid) -> String {
encode_u128_to_base32(uuid.as_u128())
encode_u128_to_base32(uuid.as_u128())
}

pub fn decode_base32_uuid(encoded: &str) -> Result<Uuid, Error> {
decode_base32_to_u128(encoded).map(|result: u128| Uuid::from_u128(result))
decode_base32_to_u128(encoded).map(|result: u128| Uuid::from_u128(result))
}


#[cfg(test)]
mod tests {
use uuid::Uuid;
Expand All @@ -76,4 +74,4 @@ mod tests {
let decoded = decode_base32_uuid(&encoded).unwrap();
assert_eq!(uuid, decoded);
}
}
}
Loading