-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
48cc174
commit 1092285
Showing
12 changed files
with
576 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
name: node | ||
|
||
on: | ||
schedule: | ||
- cron: '0 0 * * 0' | ||
workflow_dispatch: | ||
|
||
env: | ||
DOCKER_CLI_EXPERIMENTAL: enabled | ||
REPOSITORY: tgdrive/${{ github.workflow }} | ||
|
||
permissions: | ||
packages: write | ||
|
||
jobs: | ||
fetch-versions: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
latest: ${{ steps.versions.outputs.latest }} | ||
lts: ${{ steps.versions.outputs.lts }} | ||
steps: | ||
- name: Fetch Node.js versions | ||
id: versions | ||
run: | | ||
LATEST=$(curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.lts == false)][0].version') | ||
LTS=$(curl -s https://nodejs.org/dist/index.json | jq -r '[.[] | select(.lts != false)][0].version') | ||
echo "latest=${LATEST#v}" >> $GITHUB_OUTPUT | ||
echo "lts=${LTS#v}" >> $GITHUB_OUTPUT | ||
check-existing-images: | ||
needs: fetch-versions | ||
runs-on: ubuntu-latest | ||
outputs: | ||
build_latest: ${{ steps.check.outputs.build_latest }} | ||
build_lts: ${{ steps.check.outputs.build_lts }} | ||
steps: | ||
- name: Check existing images | ||
id: check | ||
run: | | ||
LATEST_VERSION=${{ needs.fetch-versions.outputs.latest }} | ||
LTS_VERSION=${{ needs.fetch-versions.outputs.lts }} | ||
check_image() { | ||
REPO="ghcr.io/${{ env.REPOSITORY }}" | ||
TAG="$1" | ||
curl -s -f -L -I -o /dev/null -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ | ||
"https://ghcr.io/v2/${REPO#ghcr.io/}/manifests/${TAG}" && echo "exists" || echo "not_exists" | ||
} | ||
LATEST_EXISTS=$(check_image $LATEST_VERSION) | ||
LTS_EXISTS=$(check_image $LTS_VERSION) | ||
echo "build_latest=$([[ $LATEST_EXISTS == "not_exists" ]] && echo "true" || echo "false")" >> $GITHUB_OUTPUT | ||
echo "build_lts=$([[ $LTS_EXISTS == "not_exists" ]] && echo "true" || echo "false")" >> $GITHUB_OUTPUT | ||
build-and-push: | ||
needs: [fetch-versions, check-existing-images] | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
arch: [amd64] | ||
version_type: [latest, lts] | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
|
||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Prepare tags and cache keys | ||
id: prep | ||
run: | | ||
if [[ "${{ matrix.version_type }}" == "latest" ]]; then | ||
VERSION=${{ needs.fetch-versions.outputs.latest }} | ||
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_latest }} | ||
else | ||
VERSION=${{ needs.fetch-versions.outputs.lts }} | ||
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_lts }} | ||
fi | ||
MAJOR_VERSION=$(echo $VERSION | cut -d. -f1) | ||
TAGS="ghcr.io/${{ env.REPOSITORY }}:${VERSION}-${{ matrix.arch }}" | ||
TAGS="${TAGS},ghcr.io/${{ env.REPOSITORY }}:${MAJOR_VERSION}-${{ matrix.arch }}" | ||
if [[ "${{ matrix.version_type }}" == "lts" ]]; then | ||
TAGS="${TAGS},ghcr.io/${{ env.REPOSITORY }}:lts-${{ matrix.arch }}" | ||
fi | ||
if [[ "${{ matrix.version_type }}" == "latest" ]]; then | ||
TAGS="${TAGS},ghcr.io/${{ env.REPOSITORY }}:latest-${{ matrix.arch }}" | ||
fi | ||
CACHE_FROM="type=gha,scope=${{ github.workflow }}-${{ matrix.version_type }}-${{ matrix.arch }}" | ||
CACHE_TO="type=gha,scope=${{ github.workflow }}-${{ matrix.version_type }}-${{ matrix.arch }}" | ||
echo "tags=${TAGS}" >> $GITHUB_OUTPUT | ||
echo "version=${VERSION}" >> $GITHUB_OUTPUT | ||
echo "major_version=${MAJOR_VERSION}" >> $GITHUB_OUTPUT | ||
echo "build_condition=${BUILD_CONDITION}" >> $GITHUB_OUTPUT | ||
echo "cache_from=${CACHE_FROM}" >> $GITHUB_OUTPUT | ||
echo "cache_to=${CACHE_TO}" >> $GITHUB_OUTPUT | ||
- name: Set Docker metadata | ||
id: docker_meta | ||
uses: docker/metadata-action@v5 | ||
with: | ||
images: ${{ env.REPOSITORY }} | ||
labels: | | ||
org.opencontainers.image.version=${{ steps.prep.outputs.version }} | ||
org.opencontainers.image.revision=${{ github.sha }} | ||
org.opencontainers.image.title=${{ env.REPOSITORY }} | ||
org.opencontainers.image.description="Node.js Distroless image" | ||
- name: Build and push image | ||
uses: docker/build-push-action@v6 | ||
if: steps.prep.outputs.build_condition == 'true' | ||
with: | ||
context: ./node | ||
push: true | ||
provenance: false | ||
labels: ${{ steps.docker_meta.outputs.labels }} | ||
build-args: | | ||
version=${{ steps.prep.outputs.version }} | ||
arch=${{ matrix.arch == 'arm64' && 'arm64v8' || matrix.arch }} | ||
cache-from: ${{ steps.prep.outputs.cache_from }} | ||
cache-to: ${{ steps.prep.outputs.cache_to }} | ||
tags: ${{ steps.prep.outputs.tags }} | ||
|
||
|
||
create-and-push-manifest: | ||
needs: [fetch-versions, check-existing-images, build-and-push] | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
version_type: [latest, lts] | ||
steps: | ||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v3 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
|
||
- name: Create and push manifests | ||
run: | | ||
if [[ "${{ matrix.version_type }}" == "latest" ]]; then | ||
VERSION=${{ needs.fetch-versions.outputs.latest }} | ||
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_latest }} | ||
else | ||
VERSION=${{ needs.fetch-versions.outputs.lts }} | ||
BUILD_CONDITION=${{ needs.check-existing-images.outputs.build_lts }} | ||
fi | ||
if [[ "${BUILD_CONDITION}" != "true" ]]; then | ||
echo "Skipping manifest creation for ${{ matrix.version_type }} as it was not built" | ||
exit 0 | ||
fi | ||
MAJOR_VERSION=$(echo $VERSION | cut -d. -f1) | ||
create_and_push_manifest() { | ||
local TAG=$1 | ||
docker manifest create --amend ghcr.io/${{ env.REPOSITORY }}:${TAG} \ | ||
ghcr.io/${{ env.REPOSITORY }}:${VERSION}-amd64 | ||
docker manifest annotate --os linux --arch amd64 ghcr.io/${{ env.REPOSITORY }}:${TAG} ghcr.io/${{ env.REPOSITORY }}:${VERSION}-amd64 | ||
#docker manifest annotate --os linux --arch arm64 ghcr.io/${{ env.REPOSITORY }}:${TAG} ghcr.io/${{ env.REPOSITORY }}:${VERSION}-arm64 | ||
docker manifest push --purge ghcr.io/${{ env.REPOSITORY }}:${TAG} | ||
} | ||
create_and_push_manifest ${VERSION} | ||
create_and_push_manifest ${MAJOR_VERSION} | ||
if [[ "${{ matrix.version_type }}" == "latest" ]]; then | ||
create_and_push_manifest latest | ||
else | ||
create_and_push_manifest lts | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
* | ||
!build.sh | ||
!patch.sh | ||
!patches |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
FROM alpine:3.16.2 as builder | ||
|
||
RUN apk update | ||
RUN apk add make g++ python3 gnupg curl file flex patch rsync texinfo | ||
|
||
ARG arch= | ||
ENV BUILD_ARCH=$arch | ||
|
||
COPY build.sh / | ||
|
||
RUN curl -Lsq -o musl-cross-make.zip https://git.zv.io/toolchains/musl-cross-make/-/archive/ed72f5171e3d4a9e92026823cbfe93e795105763/musl-cross-make-ed72f5171e3d4a9e92026823cbfe93e795105763.zip \ | ||
&& unzip -q musl-cross-make.zip \ | ||
&& mv musl-cross-make-ed72f5171e3d4a9e92026823cbfe93e795105763 musl-cross-make \ | ||
&& $(/build.sh config_mak ${BUILD_ARCH:-""} /musl-cross-make/config.mak) \ | ||
&& cd /musl-cross-make \ | ||
&& make install -j$(getconf _NPROCESSORS_ONLN) V= \ | ||
&& rm -rf /musl-cross-make | ||
|
||
ARG version=0.0.0 | ||
ENV NODE_VERSION=$version | ||
|
||
# gpg keys listed at https://github.com/nodejs/node#release-keys | ||
RUN for key in \ | ||
4ED778F539E3634C779C87C6D7062848A1AB005C \ | ||
141F07595B7B3FFE74309A937405533BE57C7D57 \ | ||
74F12602B6F1C4E913FAA37AD3A89613643B6201 \ | ||
DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 \ | ||
CC68F5A3106FF448322E48ED27F5E38D5B0A215F \ | ||
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \ | ||
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \ | ||
890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 \ | ||
C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \ | ||
108F52B48DB57BB0CC439B2997B01419BD92F80A \ | ||
A363A499291CBBC940DD62E41F10027AF002F8B0 \ | ||
; do \ | ||
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \ | ||
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \ | ||
done \ | ||
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz" \ | ||
&& curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \ | ||
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \ | ||
&& grep " node-v$NODE_VERSION.tar.xz\$" SHASUMS256.txt | sha256sum -c - | ||
|
||
ADD patch.sh / | ||
ADD patches /patches | ||
|
||
RUN tar -xf "node-v$NODE_VERSION.tar.xz" \ | ||
&& cd "node-v$NODE_VERSION" \ | ||
&& /patch.sh ${BUILD_ARCH} ${NODE_VERSION} \ | ||
&& export TARGET=$(/build.sh target ${BUILD_ARCH:-""}) \ | ||
&& export CC=$TARGET-gcc \ | ||
&& export CXX=$TARGET-g++ \ | ||
&& export AR=$TARGET-ar \ | ||
&& export NM=$TARGET-nm \ | ||
&& export RANLIB=$TARGET-ranlib \ | ||
&& export LINK=$TARGET-g++ \ | ||
&& export CXXFLAGS="-O3 -ffunction-sections -fdata-sections" \ | ||
&& export LDFLAGS="-Wl,--gc-sections,--strip-all $(/build.sh ld_flags ${BUILD_ARCH:-""})" \ | ||
&& ln -snf libc.so /usr/local/$TARGET/lib/ld-musl-*.so.1 \ | ||
&& ln -snf /usr/local/$TARGET/lib/ld-musl-*.so.1 /lib \ | ||
&& ./configure \ | ||
--partly-static \ | ||
--with-intl=small-icu \ | ||
--without-inspector \ | ||
$(/build.sh node_config ${BUILD_ARCH:-""}) \ | ||
&& make -j$(getconf _NPROCESSORS_ONLN) V= | ||
|
||
RUN echo 'node:x:1000:1000:Linux User,,,:/home/node:/bin/sh' > /tmp/passwd | ||
|
||
FROM scratch | ||
|
||
ARG version=0.0.0 | ||
|
||
LABEL org.opencontainers.image.source="https://github.com/astefanutti/scratch-node" | ||
|
||
COPY --from=builder node-v$version/out/Release/node /bin/node | ||
COPY --from=builder /lib/ld-musl-*.so.1 /lib/ | ||
COPY --from=builder /tmp/passwd /etc/passwd | ||
|
||
USER node | ||
|
||
ENTRYPOINT ["node"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
PREFIX?=tgdrive | ||
REPOSITORIES?= ghcr.io/$(PREFIX) | ||
VERSION?=22.5.1 | ||
|
||
ARCHITECTURES=amd64 arm64v8 | ||
|
||
tag-images: | ||
@for arch in $(ARCHITECTURES); do docker tag $(PREFIX)/scratch-node:${VERSION}-$${arch} $(PREFIX)/scratch-node:${TAG}-$${arch}; done | ||
|
||
move-images: | ||
@for repo in $(REPOSITORIES); do \ | ||
for arch in $(ARCHITECTURES); do \ | ||
docker tag $(PREFIX)/scratch-node:${VERSION}-$${arch} $${repo}/scratch-node:${VERSION}-$${arch}; \ | ||
done \ | ||
done | ||
|
||
build-images: | ||
@for arch in $(ARCHITECTURES); do docker build --progress=auto --build-arg version=${VERSION} --build-arg arch=$${arch} -t $(PREFIX)/scratch-node:${VERSION}-$${arch} .; done | ||
|
||
push-images: | ||
@for arch in $(ARCHITECTURES); do docker push $(PREFIX)/scratch-node:${VERSION}-$${arch}; done | ||
|
||
create-manifest: push-images | ||
docker manifest create --amend $(PREFIX)/scratch-node:$(VERSION) $(shell echo $(ARCHITECTURES) | sed -e "s~[^ ]*~$(PREFIX)/scratch-node:$(VERSION)\-&~g") | ||
docker manifest annotate --os linux --arch amd64 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-amd64 | ||
# TODO: set the CPU features as soon as the CLI exposes a --features option | ||
docker manifest annotate --os linux --arch arm --variant v6 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-arm32v6 | ||
docker manifest annotate --os linux --arch arm --variant v7 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-arm32v7 | ||
docker manifest annotate --os linux --arch arm64 --variant v8 $(PREFIX)/scratch-node:${VERSION} $(PREFIX)/scratch-node:${VERSION}-arm64v8 | ||
|
||
push-manifest: create-manifest | ||
docker manifest push --purge $(PREFIX)/scratch-node:${VERSION} |
Oops, something went wrong.