Skip to content

Commit bb024c5

Browse files
tea-artistgithub-actions[bot]caoxing9boris-wgaryli27
authored
[sync] T3289 tolerate missing link host tables in v2 delete (#3027)
Synced from teableio/teable-ee@1e6eea9 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Aries X <caoxing9@gmail.com> Co-authored-by: Boris <boris2code@outlook.com> Co-authored-by: Gary Guangyu Li <gary@teable.ai> Co-authored-by: Jocky-Teable <jocky@teable.ai> Co-authored-by: Jun Lu <hammond@teable.io> Co-authored-by: Pengap <penganpingprivte@gmail.com> Co-authored-by: Uno <uno@teable.ai> Co-authored-by: nichenqin <nichenqin@hotmail.com>
1 parent ca571d9 commit bb024c5

457 files changed

Lines changed: 18194 additions & 16634 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/docker-push.yml

Lines changed: 191 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@ concurrency:
55
cancel-in-progress: true
66

77
on:
8+
workflow_dispatch:
9+
inputs:
10+
release_timestamp:
11+
description: 'Optional UTC timestamp for release id (e.g. 2026-04-20T10:38:57Z)'
12+
required: false
13+
type: string
14+
release_sequence:
15+
description: 'Optional release id sequence suffix'
16+
required: false
17+
type: string
818
push:
919
branches:
1020
- develop
11-
tags:
12-
- 'v*'
1321
paths:
1422
- 'apps/nestjs-backend/**'
1523
- 'apps/nextjs-app/**'
@@ -18,21 +26,65 @@ on:
1826
- 'scripts/**'
1927

2028
jobs:
29+
prepare-release:
30+
runs-on: ubuntu-latest
31+
outputs:
32+
release_id: ${{ steps.release.outputs.release_id }}
33+
release_timestamp: ${{ steps.release.outputs.release_timestamp }}
34+
release_sequence: ${{ steps.release.outputs.release_sequence }}
35+
steps:
36+
- name: Compute release id
37+
id: release
38+
env:
39+
INPUT_RELEASE_TIMESTAMP: ${{ inputs.release_timestamp }}
40+
INPUT_RELEASE_SEQUENCE: ${{ inputs.release_sequence }}
41+
run: |
42+
RELEASE_TIMESTAMP="${INPUT_RELEASE_TIMESTAMP}"
43+
if [ -z "$RELEASE_TIMESTAMP" ]; then
44+
RELEASE_TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
45+
fi
46+
47+
RELEASE_SEQUENCE="${INPUT_RELEASE_SEQUENCE:-${GITHUB_RUN_NUMBER:-1}}"
48+
RELEASE_TIMESTAMP_NO_MS=$(printf '%s' "$RELEASE_TIMESTAMP" | sed -E 's/\.[0-9]{3}Z$/Z/')
49+
RELEASE_TIMESTAMP_TAG=$(printf '%s' "$RELEASE_TIMESTAMP_NO_MS" | tr ':' '-')
50+
RELEASE_ID="release.${RELEASE_TIMESTAMP_TAG}.${RELEASE_SEQUENCE}"
51+
52+
echo "release_timestamp=$RELEASE_TIMESTAMP_NO_MS" >> "$GITHUB_OUTPUT"
53+
echo "release_sequence=$RELEASE_SEQUENCE" >> "$GITHUB_OUTPUT"
54+
echo "release_id=$RELEASE_ID" >> "$GITHUB_OUTPUT"
55+
56+
echo "Release timestamp: $RELEASE_TIMESTAMP_NO_MS"
57+
echo "Release sequence: $RELEASE_SEQUENCE"
58+
echo "Release id: $RELEASE_ID"
59+
2160
build-push:
61+
needs: prepare-release
2262
strategy:
2363
matrix:
24-
target: [app, db-migrate]
25-
arch: [amd64, arm64]
2664
include:
2765
- target: app
2866
file: Dockerfile
2967
image: teable-community
68+
platform: linux/amd64
69+
platform_key: linux-amd64
70+
runner: ubuntu-latest
71+
- target: app
72+
file: Dockerfile
73+
image: teable-community
74+
platform: linux/arm64
75+
platform_key: linux-arm64
76+
runner: ubuntu-24.04-arm
3077
- target: db-migrate
3178
file: Dockerfile.db-migrate
3279
image: teable-db-migrate-community
33-
- arch: amd64
80+
platform: linux/amd64
81+
platform_key: linux-amd64
3482
runner: ubuntu-latest
35-
- arch: arm64
83+
- target: db-migrate
84+
file: Dockerfile.db-migrate
85+
image: teable-db-migrate-community
86+
platform: linux/arm64
87+
platform_key: linux-arm64
3688
runner: ubuntu-24.04-arm
3789
runs-on: ${{ matrix.runner }}
3890

@@ -47,51 +99,46 @@ jobs:
4799
username: ${{ github.actor }}
48100
password: ${{ secrets.PACKAGES_KEY }}
49101

50-
- name: Login to Docker Hub registry
51-
uses: docker/login-action@v3
52-
with:
53-
username: ${{ secrets.DOCKER_HUB_NAME }}
54-
password: ${{ secrets.DOCKER_HUB_AK }}
55-
56-
- name: Login to Ali container registry
57-
uses: docker/login-action@v3
58-
with:
59-
registry: registry.cn-shenzhen.aliyuncs.com
60-
username: ${{ secrets.ALI_DOCKER_USERNAME }}
61-
password: ${{ secrets.ALI_DOCKER_PASSWORD }}
62-
63102
- uses: actions/setup-node@v4
64103
with:
65104
node-version: 22.18.0
66-
- name: ⚙️ Install zx
67-
run: npm install -g zx
68105

69-
- name: ⚙️ Docker meta
70-
id: meta
71-
uses: docker/metadata-action@v5
106+
- name: Set up Docker Buildx
107+
uses: docker/setup-buildx-action@v3
108+
109+
- name: Build and push by digest
110+
id: build
111+
uses: docker/build-push-action@v6
72112
with:
73-
images: |
74-
registry.cn-shenzhen.aliyuncs.com/teable/${{ matrix.image }}
75-
ghcr.io/teableio/${{ matrix.image }}
76-
docker.io/teableio/${{ matrix.image }}
77-
tags: |
78-
type=sha,format=long
79-
type=raw,value=latest
113+
context: .
114+
file: dockers/teable/${{ matrix.file }}
115+
platforms: ${{ matrix.platform }}
116+
build-args: |
117+
ENABLE_CSP=false
118+
BUILD_VERSION=${{ needs.prepare-release.outputs.release_id }}
119+
cache-from: type=gha,scope=release-community-${{ matrix.target }}-${{ matrix.platform_key }}
120+
cache-to: type=gha,mode=max,scope=release-community-${{ matrix.target }}-${{ matrix.platform_key }},ignore-error=true
121+
outputs: type=image,name=ghcr.io/teableio/${{ matrix.image }},push-by-digest=true,name-canonical=true,push=true
122+
provenance: false
80123

81-
- name: 📦 Build and push
124+
- name: Export digest artifact
82125
run: |
83-
zx scripts/build-image.mjs --file=dockers/teable/${{ matrix.file }} \
84-
--build-arg="ENABLE_CSP=false" \
85-
--tag="${{ steps.meta.outputs.tags }}" \
86-
--platform="linux/${{ matrix.arch }}" \
87-
--push
88-
89-
create-manifest:
90-
needs: build-push
126+
mkdir -p /tmp/digests
127+
echo "${{ steps.build.outputs.digest }}" > "/tmp/digests/${{ matrix.platform_key }}.digest"
128+
129+
- name: Upload digest artifact
130+
uses: actions/upload-artifact@v4
131+
with:
132+
name: digests-${{ matrix.target }}-${{ matrix.platform_key }}
133+
path: /tmp/digests/${{ matrix.platform_key }}.digest
134+
if-no-files-found: error
135+
retention-days: 1
136+
137+
merge-manifests:
138+
needs: [prepare-release, build-push]
91139
runs-on: ubuntu-latest
92140
strategy:
93141
matrix:
94-
target: [app, db-migrate]
95142
include:
96143
- target: app
97144
image: teable-community
@@ -106,30 +153,113 @@ jobs:
106153
username: ${{ github.actor }}
107154
password: ${{ secrets.PACKAGES_KEY }}
108155

109-
- name: Login to Docker Hub registry
110-
uses: docker/login-action@v3
156+
- name: Set up Docker Buildx
157+
uses: docker/setup-buildx-action@v3
158+
159+
- name: Docker meta for canonical image
160+
id: meta
161+
uses: docker/metadata-action@v5
111162
with:
112-
username: ${{ secrets.DOCKER_HUB_NAME }}
113-
password: ${{ secrets.DOCKER_HUB_AK }}
163+
images: ghcr.io/teableio/${{ matrix.image }}
164+
tags: |
165+
type=raw,value=beta
166+
type=raw,value=${{ needs.prepare-release.outputs.release_id }}
167+
type=raw,value=${{ github.sha }}
114168
115-
- name: Login to Ali container registry
116-
uses: docker/login-action@v3
169+
- name: Download digest artifacts
170+
uses: actions/download-artifact@v4
117171
with:
118-
registry: registry.cn-shenzhen.aliyuncs.com
119-
username: ${{ secrets.ALI_DOCKER_USERNAME }}
120-
password: ${{ secrets.ALI_DOCKER_PASSWORD }}
172+
path: /tmp/digests/${{ matrix.target }}
173+
pattern: digests-${{ matrix.target }}-*
174+
merge-multiple: true
175+
176+
- name: Create manifests
177+
env:
178+
META_JSON: ${{ steps.meta.outputs.json }}
179+
CANONICAL_IMAGE: ghcr.io/teableio/${{ matrix.image }}
180+
run: |
181+
mapfile -t TAGS < <(jq -r '.tags[]' <<<"$META_JSON")
182+
mapfile -t DIGEST_FILES < <(find "/tmp/digests/${{ matrix.target }}" -type f -name '*.digest' | sort)
183+
184+
if [ "${#DIGEST_FILES[@]}" -eq 0 ]; then
185+
echo "No digest artifacts found for ${{ matrix.target }}" >&2
186+
exit 1
187+
fi
188+
189+
SOURCES=()
190+
for digest_file in "${DIGEST_FILES[@]}"; do
191+
digest="$(tr -d '\n' < "$digest_file")"
192+
SOURCES+=("${CANONICAL_IMAGE}@${digest}")
193+
done
194+
195+
for full_tag in "${TAGS[@]}"; do
196+
tag_name="${full_tag##*:}"
197+
if [ -z "$tag_name" ]; then
198+
continue
199+
fi
200+
docker buildx imagetools create \
201+
--tag "${CANONICAL_IMAGE}:${tag_name}" \
202+
"${SOURCES[@]}"
203+
done
204+
205+
sync-dockerhub:
206+
needs: [prepare-release, build-push, merge-manifests]
207+
runs-on: ubuntu-latest
208+
steps:
209+
- name: Install skopeo
210+
run: |
211+
sudo apt-get update
212+
sudo apt-get install -y skopeo
213+
214+
- name: Sync images to Docker Hub
215+
env:
216+
SRC_CREDS: ${{ github.actor }}:${{ secrets.PACKAGES_KEY }}
217+
DST_CREDS: ${{ secrets.DOCKER_HUB_NAME }}:${{ secrets.DOCKER_HUB_AK }}
218+
TAGS: beta,${{ needs.prepare-release.outputs.release_id }},${{ github.sha }}
219+
run: |
220+
set -euo pipefail
221+
222+
IFS=',' read -ra TAG_LIST <<< "$TAGS"
223+
IMAGES=("teable-community" "teable-db-migrate-community")
224+
225+
for image in "${IMAGES[@]}"; do
226+
for tag in "${TAG_LIST[@]}"; do
227+
[ -n "$tag" ] || continue
228+
skopeo copy --all \
229+
--src-creds="$SRC_CREDS" \
230+
--dest-creds="$DST_CREDS" \
231+
"docker://ghcr.io/teableio/${image}:${tag}" \
232+
"docker://docker.io/teableio/${image}:${tag}"
233+
done
234+
done
121235
122-
- name: Create and push manifest
236+
sync-aliyun:
237+
needs: [prepare-release, build-push, merge-manifests]
238+
runs-on: ubuntu-latest
239+
steps:
240+
- name: Install skopeo
123241
run: |
124-
REGISTRIES=("registry.cn-shenzhen.aliyuncs.com/teable" "ghcr.io/teableio" "docker.io/teableio")
125-
TAGS=("latest" "sha-${{ github.sha }}")
126-
127-
for REGISTRY in "${REGISTRIES[@]}"; do
128-
for TAG in "${TAGS[@]}"; do
129-
docker manifest create $REGISTRY/${{ matrix.image }}:$TAG \
130-
$REGISTRY/${{ matrix.image }}:${TAG}-amd64 \
131-
$REGISTRY/${{ matrix.image }}:${TAG}-arm64
132-
133-
docker manifest push $REGISTRY/${{ matrix.image }}:$TAG
242+
sudo apt-get update
243+
sudo apt-get install -y skopeo
244+
245+
- name: Sync images to Aliyun
246+
env:
247+
SRC_CREDS: ${{ github.actor }}:${{ secrets.PACKAGES_KEY }}
248+
DST_CREDS: ${{ secrets.ALI_DOCKER_USERNAME }}:${{ secrets.ALI_DOCKER_PASSWORD }}
249+
TAGS: beta,${{ needs.prepare-release.outputs.release_id }},${{ github.sha }}
250+
run: |
251+
set -euo pipefail
252+
253+
IFS=',' read -ra TAG_LIST <<< "$TAGS"
254+
IMAGES=("teable-community" "teable-db-migrate-community")
255+
256+
for image in "${IMAGES[@]}"; do
257+
for tag in "${TAG_LIST[@]}"; do
258+
[ -n "$tag" ] || continue
259+
skopeo copy --all \
260+
--src-creds="$SRC_CREDS" \
261+
--dest-creds="$DST_CREDS" \
262+
"docker://ghcr.io/teableio/${image}:${tag}" \
263+
"docker://registry.cn-shenzhen.aliyuncs.com/teable/${image}:${tag}"
134264
done
135265
done

.github/workflows/manual-preview.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ env:
1919
INSTANCE_DOMAIN: pr-${{ github.event.pull_request.number }}
2020
DISPLAY_NAME: 'teable-pr-${{ github.event.pull_request.number }}'
2121
MAIN_IMAGE_REPOSITORY: registry.cn-shenzhen.aliyuncs.com/teable/teable
22-
IMAGE_TAG: ${{ github.sha }}-amd64
22+
IMAGE_TAG: ${{ github.sha }}
2323

2424
concurrency:
2525
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}

.github/workflows/preview-cleanup.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ env:
1010
INSTANCE_DOMAIN: pr-${{ github.event.pull_request.number }}
1111
DISPLAY_NAME: "teable-pr-${{ github.event.pull_request.number }}"
1212
MAIN_IMAGE_REPOSITORY: registry.cn-shenzhen.aliyuncs.com/teable/teable
13-
IMAGE_TAG: ${{ github.sha }}-amd64
13+
IMAGE_TAG: ${{ github.sha }}
1414

1515
jobs:
1616
cleanup:
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Promote Latest Tag
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
release_id:
7+
description: 'Existing build-time release id to promote, e.g. release.2026-04-20T10-38-57Z.1'
8+
required: true
9+
type: string
10+
11+
jobs:
12+
promote-latest:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
target: [app, db-migrate]
17+
include:
18+
- target: app
19+
image: teable-community
20+
- target: db-migrate
21+
image: teable-db-migrate-community
22+
23+
steps:
24+
- name: Login to GitHub container registry
25+
uses: docker/login-action@v3
26+
with:
27+
registry: ghcr.io
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.PACKAGES_KEY }}
30+
31+
- name: Login to Docker Hub registry
32+
uses: docker/login-action@v3
33+
with:
34+
username: ${{ secrets.DOCKER_HUB_NAME }}
35+
password: ${{ secrets.DOCKER_HUB_AK }}
36+
37+
- name: Login to Ali container registry
38+
uses: docker/login-action@v3
39+
with:
40+
registry: registry.cn-shenzhen.aliyuncs.com
41+
username: ${{ secrets.ALI_DOCKER_USERNAME }}
42+
password: ${{ secrets.ALI_DOCKER_PASSWORD }}
43+
44+
- name: Set up Docker Buildx
45+
uses: docker/setup-buildx-action@v3
46+
47+
- name: Promote release tag to latest
48+
run: |
49+
REGISTRIES=("registry.cn-shenzhen.aliyuncs.com/teable" "ghcr.io/teableio" "docker.io/teableio")
50+
51+
for REGISTRY in "${REGISTRIES[@]}"; do
52+
docker buildx imagetools create \
53+
--tag "$REGISTRY/${{ matrix.image }}:latest" \
54+
"$REGISTRY/${{ matrix.image }}:${{ inputs.release_id }}"
55+
done

0 commit comments

Comments
 (0)