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
9 changes: 0 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,9 @@ jobs:
- name: Checkout code
uses: actions/checkout@v5

# - name: Set up bashcov
# uses: infertux/bashcov/.github/actions/set-up-bashcov@master

- name: Install lcov
run: sudo apt-get update && sudo apt-get install -y lcov

# - name: Run tests with coverage
# run: |
# pipenv run pytest --cov --cov-report=lcov
# # bashcov ./commit_changes_test.sh
# # ./merge_lcov.sh src merged.lcov

- name: Coverage Badge
uses: ImBIOS/lcov-coverage-badge@b548b874a74d1c0bb832498745ff98ccb6a81430
with:
Expand Down
255 changes: 206 additions & 49 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,115 @@ name: Release

on:
schedule:
- cron: "0 0 * * *" # Every day at midnight
- cron: "0 0 * * *"
workflow_dispatch:
inputs:
bun-versions:
description: "Bun version, comma separated (e.g. 0.0.1,0.0.2,1.0.8-canary.20231104.1)"
description: "Bun version, comma separated (e.g. 0.0.1,1.0.8-canary.20231104.1)"
required: false
default: ""
nodejs-version:
description: "Node.js version, comma separated (e.g. 14.7.4,17.3.8,18.4.5)"
description: "Node.js version, comma separated (e.g. 18.4.5,20.11.0)"
required: false
default: ""
distros:
description: "Distro, comma separated (e.g. alpine,debian-slim,debian)"
required: false
default: ""
# TODO: To be implemented
# skip-check:
# description: "Skip version check"
# required: false
# default: "true"

env:
REGISTRY: imbios
PLATFORMS: linux/amd64,linux/arm64
NODE_MAJOR_VERSIONS_TO_CHECK: 20,22,24,25
NODE_VERSIONS_TO_BUILD: ""
BUN_TAGS_TO_CHECK: canary,latest
BUN_VERSIONS_TO_BUILD: ""
DISTROS: alpine,debian-slim,debian
DISTROS: ${{ inputs.distros || 'alpine,debian-slim,debian' }}
VERSIONS_RELEASE: versions
INPUT_BUN_VERSIONS: ${{ inputs.bun-versions }}
INPUT_NODE_VERSIONS: ${{ inputs.nodejs-version }}

jobs:
# TODO: To be implemented
# test-job:
# uses: ./.github/workflows/ci.yml
build-job:
# TODO: To be implemented
# needs: test-job
setup:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
matrix: ${{ steps.matrix.outputs.matrix }}
sync_sha: ${{ steps.sync.outputs.sync_sha }}
steps:
- name: Checkout code
uses: actions/checkout@v5
- uses: actions/checkout@v5

- uses: oven-sh/setup-bun@635640504f6d7197d3bb29876a652f671028dc97
- run: bun install
- run: bun install --frozen-lockfile --ignore-scripts

- name: Check for new releases of nodejs and bun
if: ${{ inputs.nodejs-version == '' && inputs.bun-versions == '' && inputs.distros == '' }}
- name: Download version state
run: |
set -e
echo "NODE_VERSIONS_TO_BUILD=$(bun run check-bun-node.ts --node ${{ env.NODE_MAJOR_VERSIONS_TO_CHECK }})" >> $GITHUB_ENV
echo "BUN_VERSIONS_TO_BUILD=$(bun run check-bun-node.ts --bun ${{ env.BUN_TAGS_TO_CHECK }})" >> $GITHUB_ENV
gh release download "${{ env.VERSIONS_RELEASE }}" -p versions.json || echo '{}' > versions.json
cat versions.json
env:
GH_TOKEN: ${{ github.token }}

- name: Seed stats cache for the stats site
continue-on-error: true
env:
STATS_SEED: ${{ secrets.BUN_NODE_STATS_SEED }}
run: |
DOCKER=$(curl -fsS --proto '=https' --tlsv1.2 "https://hub.docker.com/v2/repositories/imbios/bun-node/")
TAGS=$(curl -fsS --proto '=https' --tlsv1.2 "https://hub.docker.com/v2/repositories/imbios/bun-node/tags/?page_size=1")
GH=$(curl -fsS --proto '=https' --tlsv1.2 "https://api.github.com/repos/ImBIOS/bun-node")
jq -n \
--argjson d "$DOCKER" \
--argjson t "$TAGS" \
--argjson g "$GH" \
'{docker: {pull_count: $d.pull_count, star_count: $d.star_count, last_updated: $d.last_updated, count: $t.count}, github: {stargazers_count: $g.stargazers_count, forks_count: $g.forks_count, open_issues_count: $g.open_issues_count, pushed_at: $g.pushed_at}}' \
> /tmp/stats-seed.json
curl -fsS --proto '=https' --tlsv1.2 -X POST \
-H "Authorization: Bearer ${STATS_SEED}" \
-H "Content-Type: application/json" \
--data-binary @/tmp/stats-seed.json \
https://bun-node.imbios.dev/internal/seed

- name: Sync supported Node.js majors
id: sync
run: |
bun run check-bun-node.ts --sync --versions versions.json
if [[ -n "$(git status --porcelain)" ]]; then
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add src templates
git commit -m "chore: sync Dockerfiles with supported Node.js majors"
git push origin main
echo "sync_sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
else
echo "sync_sha=$GITHUB_SHA" >> "$GITHUB_OUTPUT"
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Generate build matrix
id: matrix
env:
DISTROS: ${{ env.DISTROS }}
INPUT_BUN_VERSIONS: ${{ env.INPUT_BUN_VERSIONS }}
INPUT_NODE_VERSIONS: ${{ env.INPUT_NODE_VERSIONS }}
run: |
MATRIX=$(bun run check-bun-node.ts --matrix --versions versions.json)
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
echo "matrix=$MATRIX"

build:
needs: setup
runs-on: ubuntu-latest
permissions:
contents: read
if: ${{ fromJson(needs.setup.outputs.matrix).include[0] != null }}
strategy:
fail-fast: false
max-parallel: 12
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
steps:
- uses: actions/checkout@v5
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
ref: ${{ needs.setup.outputs.sync_sha }}
persist-credentials: false

- name: Setup Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
Expand All @@ -64,37 +120,138 @@ jobs:
password: ${{ secrets.DOCKER_TOKEN }}

- uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08
name: Build and push Docker images
name: Build and push
env:
REGISTRY: ${{ env.REGISTRY }}
PLATFORMS: ${{ env.PLATFORMS }}
MATRIX_BUN_VERSION: ${{ matrix.bun_version }}
MATRIX_NODE_VERSION: ${{ matrix.node_version }}
MATRIX_NODE_MAJOR: ${{ matrix.node_major }}
MATRIX_CODENAME: ${{ matrix.codename }}
MATRIX_DISTRO: ${{ matrix.distro }}
MATRIX_LATEST_CANDIDATE: ${{ matrix.latest_candidate }}
with:
timeout_minutes: 120
timeout_minutes: 90
max_attempts: 3
retry_on: error
command: ./build_updated.sh
command: ./build_single.sh --bun "$MATRIX_BUN_VERSION" --node "$MATRIX_NODE_VERSION" --node-major "$MATRIX_NODE_MAJOR" --codename "$MATRIX_CODENAME" --distro "$MATRIX_DISTRO" --latest-candidate "$MATRIX_LATEST_CANDIDATE"

- name: Name the build result per combination
id: name-result
env:
REGISTRY: ${{ env.REGISTRY }}
PLATFORMS: ${{ env.PLATFORMS }}
NODE_VERSIONS_TO_BUILD: ${{ env.NODE_VERSIONS_TO_BUILD || inputs.nodejs-version }}
BUN_VERSIONS_TO_BUILD: ${{ env.BUN_VERSIONS_TO_BUILD || inputs.bun-versions }}
DISTROS: ${{ env.DISTROS || inputs.distros }}
MATRIX_BUN_TAG: ${{ matrix.bun_tag }}
MATRIX_BUN_VERSION: ${{ matrix.bun_version }}
MATRIX_NODE_VERSION: ${{ matrix.node_version }}
MATRIX_DISTRO: ${{ matrix.distro }}
run: |
RESULT_FILE="build_success-${MATRIX_BUN_TAG}-${MATRIX_BUN_VERSION}-${MATRIX_NODE_VERSION}-${MATRIX_DISTRO}.json"
mv build_success.json "$RESULT_FILE"
echo "result_file=$RESULT_FILE" >> "$GITHUB_OUTPUT"

- name: Upload build result
uses: actions/upload-artifact@v4
with:
name: build-success-${{ matrix.bun_tag }}-${{ matrix.bun_version }}-${{ matrix.node_version }}-${{ matrix.distro }}
path: ${{ steps.name-result.outputs.result_file }}
if-no-files-found: error
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Commit changes
run: ./commit_changes.sh
finalize:
needs: [setup, build]
runs-on: ubuntu-latest
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
permissions:
contents: write
if: ${{ always() && needs.build.result != 'skipped' && needs.build.result != 'cancelled' && !cancelled() }}
steps:
- uses: actions/checkout@v5
with:
ref: ${{ needs.setup.outputs.sync_sha }}
persist-credentials: false

- name: Download version state
run: |
gh release download "${{ env.VERSIONS_RELEASE }}" -p versions.json || echo '{}' > versions.json
env:
BUN_VERSIONS_TO_BUILD: ${{ env.BUN_VERSIONS_TO_BUILD }}
NODE_VERSIONS_TO_BUILD: ${{ env.NODE_VERSIONS_TO_BUILD }}
DISTROS: ${{ env.DISTROS }}
- name: Pull changes
run: git pull -r
- name: Push changes
uses: ad-m/github-push-action@77c5b412c50b723d2a4fbc6d71fb5723bcd439aa
GH_TOKEN: ${{ github.token }}

- name: Download build results
uses: actions/download-artifact@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
pattern: build-success-*
merge-multiple: true
path: updates

- name: Merge version state
id: merge
run: |
ls -la updates
if [[ -z "$(ls -A updates 2>/dev/null)" ]]; then
echo "no successful builds to finalize, skipping"
echo "updates_found=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "updates_found=true" >> "$GITHUB_OUTPUT"
jq -s 'reduce .[] as $u ({}; . * $u)' versions.json updates/*.json > versions.json.tmp
jq 'del(._needs_rebuild)' versions.json.tmp > versions.json
rm -f versions.json.tmp
cat versions.json

- name: Point latest at the newest candidate
if: ${{ steps.merge.outputs.updates_found == 'true' }}
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_TOKEN: ${{ secrets.DOCKER_TOKEN }}
run: |
candidate=$(jq -s 'map(select(.latest_candidate == true)) | .[0]' updates/*.json)
if [ "$candidate" != "null" ]; then
bun_version=$(echo "$candidate" | jq -r '.bun.latest | sub("^v"; "")')
node_version=$(echo "$candidate" | jq -r '.nodejs | to_entries[0].value.version | sub("^v"; "")')
echo "${DOCKER_TOKEN}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker buildx imagetools create --tag "${{ env.REGISTRY }}/bun-node:latest" "${{ env.REGISTRY }}/bun-node:${bun_version}-${node_version}-debian"
else
echo "no latest candidate in this run, skipping"
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Upload version state
if: ${{ steps.merge.outputs.updates_found == 'true' }}
run: |
gh release create "${{ env.VERSIONS_RELEASE }}" versions.json --title "Versions State" --notes "" || \
gh release upload "${{ env.VERSIONS_RELEASE }}" versions.json --clobber
env:
GH_TOKEN: ${{ github.token }}

- name: Write release summary
if: ${{ steps.merge.outputs.updates_found == 'true' }}
run: |
{
echo "## Release summary"
echo ""
echo "Built $(ls updates | wc -l) image combination(s):"
echo ""
for file in updates/*.json; do
bun=$(jq -r '.bun | to_entries[] | "\(.key)=\(.value)"' "$file" | tr '\n' ' ')
node=$(jq -r '.nodejs | to_entries[] | "node\(.key)=\(.value.version)"' "$file" | tr '\n' ' ')
echo "- $node | $bun"
done
} >> "$GITHUB_STEP_SUMMARY"
gh release edit "${{ env.VERSIONS_RELEASE }}" --notes "$(cat "$GITHUB_STEP_SUMMARY")"
env:
GH_TOKEN: ${{ github.token }}

rerun-failed-jobs:
runs-on: ubuntu-latest
needs: [build-job]
if: failure()
needs: [build]
permissions:
actions: write
if: ${{ failure() && needs.build.result == 'failure' && github.run_attempt < 3 }}
steps:
- name: Rerun failed jobs in the current workflow
- name: Rerun failed build jobs
env:
GH_TOKEN: ${{ github.token }}
run: gh run rerun ${{ github.run_id }} --repo ${{ github.repository }} --failed
run: |
failed=$(gh run view ${{ github.run_id }} --repo ${{ github.repository }} --json jobs \
--jq '[.jobs[] | select((.name | startswith("build")) and .conclusion == "failure") | .databaseId] | join(" ")')
if [ -n "$failed" ]; then
for job in $failed; do
gh run rerun ${{ github.run_id }} --repo ${{ github.repository }} --job "$job" || true
done
Comment thread
coderabbitai[bot] marked this conversation as resolved.
fi
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
coverage.info
coverage/
node_modules/
.wrangler/
.cloudflare/
Loading
Loading