ci: add aarch64-unknown-linux-gnu build and multi-arch Docker support #2

This commit is contained in:
rustmailer
2025-11-20 10:57:05 +08:00
parent 1f77ed91a7
commit b05bb4f48e
3 changed files with 31 additions and 28 deletions
+15 -4
View File
@@ -21,6 +21,8 @@ jobs:
os: ubuntu-latest os: ubuntu-latest
- target: x86_64-unknown-linux-musl - target: x86_64-unknown-linux-musl
os: ubuntu-latest os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
- target: x86_64-apple-darwin - target: x86_64-apple-darwin
os: macos-latest os: macos-latest
- target: x86_64-pc-windows-msvc - target: x86_64-pc-windows-msvc
@@ -55,7 +57,6 @@ jobs:
- name: Install musl-tools (Linux musl only) - name: Install musl-tools (Linux musl only)
if: matrix.target == 'x86_64-unknown-linux-musl' if: matrix.target == 'x86_64-unknown-linux-musl'
run: sudo apt-get update && sudo apt-get install -y musl-tools run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Build Rust backend - name: Build Rust backend
run: cargo build --release --features vendored-openssl --target=${{ matrix.target }} run: cargo build --release --features vendored-openssl --target=${{ matrix.target }}
@@ -144,15 +145,24 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Download Linux musl artifact - name: Download Linux musl artifact (amd64)
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:
name: x86_64-unknown-linux-musl name: x86_64-unknown-linux-musl
path: artifacts path: artifacts/amd64
- name: Download Linux artifact (arm64)
uses: actions/download-artifact@v4
with:
name: aarch64-unknown-linux-gnu
path: artifacts/arm64
- name: Prepare Docker context - name: Prepare Docker context
run: | run: |
tar -xzf artifacts/${{ env.BINARY_NAME }}-*.tar.gz -C docker mkdir -p docker/amd64 docker/arm64
tar -xzf artifacts/amd64/${{ env.BINARY_NAME }}-*.tar.gz -C docker/amd64
tar -xzf artifacts/arm64/${{ env.BINARY_NAME }}-*.tar.gz -C docker/arm64
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
@@ -167,6 +177,7 @@ jobs:
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
context: ./docker context: ./docker
platforms: linux/amd64,linux/arm64
push: true push: true
tags: | tags: |
rustmailer/bichon:${{ github.ref_name }} rustmailer/bichon:${{ github.ref_name }}
+2 -3
View File
@@ -1,6 +1,7 @@
# Use Debian bullseye-slim as the base image for newer OpenSSL # Use Debian bullseye-slim as the base image for newer OpenSSL
FROM ubuntu:24.04 FROM ubuntu:24.04
ARG CRATE_VERSION ARG CRATE_VERSION
ARG TARGETARCH
# Set maintainer metadata # Set maintainer metadata
LABEL maintainer="rustmailer <rustmailer.git@gmail.com>" LABEL maintainer="rustmailer <rustmailer.git@gmail.com>"
@@ -11,15 +12,13 @@ LABEL description="Dockerized Bichon service"
WORKDIR /opt/bichon WORKDIR /opt/bichon
# Copy compiled binary (ensure it's statically linked or compatible with bullseye) # Copy compiled binary (ensure it's statically linked or compatible with bullseye)
COPY bichon /opt/bichon/bichon COPY ${TARGETARCH}/bichon /opt/bichon/bichon
COPY LICENSE /opt/bichon/ COPY LICENSE /opt/bichon/
# Set proper permissions # Set proper permissions
RUN chmod +x /opt/bichon/bichon RUN chmod +x /opt/bichon/bichon
# Install ca-certificates to ensure HTTPS certificate verification works correctly # Install ca-certificates to ensure HTTPS certificate verification works correctly
RUN apt update && apt install -y ca-certificates && rm -rf /var/lib/apt/lists/*
RUN apt update && apt install -y ca-certificates curl && rm -rf /var/lib/apt/lists/* RUN apt update && apt install -y ca-certificates curl && rm -rf /var/lib/apt/lists/*
# Create data directory # Create data directory
RUN mkdir -p /data RUN mkdir -p /data
+14 -21
View File
@@ -16,7 +16,6 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
use std::{path::PathBuf, time::Duration}; use std::{path::PathBuf, time::Duration};
use chrono::Utc; use chrono::Utc;
@@ -145,20 +144,20 @@ async fn test2() {
let delete_term3 = Term::from_field_u64(a, 3u64); let delete_term3 = Term::from_field_u64(a, 3u64);
let operations = vec![ let operations = vec![
//UserOperation::Delete(delete_term1), UserOperation::Delete(delete_term1),
UserOperation::Add(doc!( UserOperation::Add(doc!(
a => 1u64, a => 1u64,
b => "test1" b => "v1"
)), )),
//UserOperation::Delete(delete_term2), UserOperation::Delete(delete_term2),
UserOperation::Add(doc!( UserOperation::Add(doc!(
a => 2u64, a => 2u64,
b => "test1" b => "v1"
)), )),
//UserOperation::Delete(delete_term3), UserOperation::Delete(delete_term3),
UserOperation::Add(doc!( UserOperation::Add(doc!(
a => 3u64, a => 3u64,
b => "test1" b => "v1"
)), )),
]; ];
@@ -166,13 +165,10 @@ async fn test2() {
index_writer.commit().unwrap(); index_writer.commit().unwrap();
let reader = index.reader().unwrap(); let reader = index.reader().unwrap();
let searcher = reader.searcher(); let searcher = reader.searcher();
let tq = TermQuery::new(Term::from_field_u64(a, 3), IndexRecordOption::Basic); let tq = TermQuery::new(Term::from_field_u64(a, 3), IndexRecordOption::Basic);
let docs = searcher.search(&tq, &TopDocs::with_limit(1)).unwrap(); let docs = searcher.search(&tq, &TopDocs::with_limit(1)).unwrap();
assert!(docs.first().is_some());
if let Some((_, doc_address)) = docs.first() { if let Some((_, doc_address)) = docs.first() {
let old_doc: TantivyDocument = searcher.doc_async(*doc_address).await.unwrap(); let old_doc: TantivyDocument = searcher.doc_async(*doc_address).await.unwrap();
@@ -181,12 +177,14 @@ async fn test2() {
if field == a { if field == a {
new_doc.add_field_value(a, value); new_doc.add_field_value(a, value);
} }
if field == b {
assert_eq!(Some("v1"), value.as_str())
} }
new_doc.add_text(b, "test2"); }
new_doc.add_text(b, "v2");
let delete_term = Term::from_field_u64(a, 3); let delete_term = Term::from_field_u64(a, 3);
index_writer.delete_term(delete_term); index_writer.delete_term(delete_term);
index_writer.commit().unwrap();
index_writer.add_document(new_doc).unwrap(); index_writer.add_document(new_doc).unwrap();
index_writer.commit().unwrap(); index_writer.commit().unwrap();
} }
@@ -194,17 +192,14 @@ async fn test2() {
reader.reload().unwrap(); reader.reload().unwrap();
let searcher = reader.searcher(); let searcher = reader.searcher();
let docs = searcher.search(&tq, &TopDocs::with_limit(1)).unwrap(); let docs = searcher.search(&tq, &TopDocs::with_limit(1)).unwrap();
assert!(docs.first().is_some());
if let Some((_, doc_address)) = docs.first() { if let Some((_, doc_address)) = docs.first() {
let doc: TantivyDocument = searcher.doc_async(*doc_address).await.unwrap(); let doc: TantivyDocument = searcher.doc_async(*doc_address).await.unwrap();
for (field, value) in doc.field_values() { for (field, value) in doc.field_values() {
if field == b { if field == b {
let value = value.as_str(); assert_eq!(Some("v2"), value.as_str())
println!("{:#?}", value);
} }
} }
} else {
println!("not found")
} }
let delete_term = Term::from_field_u64(a, 3); let delete_term = Term::from_field_u64(a, 3);
@@ -214,7 +209,7 @@ async fn test2() {
reader.reload().unwrap(); reader.reload().unwrap();
let searcher = reader.searcher(); let searcher = reader.searcher();
let docs = searcher.search(&tq, &TopDocs::with_limit(1)).unwrap(); let docs = searcher.search(&tq, &TopDocs::with_limit(1)).unwrap();
assert!(docs.first().is_none());
if let Some((_, doc_address)) = docs.first() { if let Some((_, doc_address)) = docs.first() {
let doc: TantivyDocument = searcher.doc_async(*doc_address).await.unwrap(); let doc: TantivyDocument = searcher.doc_async(*doc_address).await.unwrap();
for (field, value) in doc.field_values() { for (field, value) in doc.field_values() {
@@ -223,7 +218,5 @@ async fn test2() {
println!("{:#?}", value); println!("{:#?}", value);
} }
} }
} else {
println!("not found")
} }
} }