diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..c6b4cf8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +--- +version: 2 +updates: + # raise PRs for gem updates + - package-ecosystem: bundler + directory: "/" + schedule: + interval: daily + time: "13:00" + open-pull-requests-limit: 10 + + # Maintain dependencies for GitHub Actions + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + time: "13:00" + open-pull-requests-limit: 10 + + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" + time: "13:00" + open-pull-requests-limit: 10 diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000..7899de8 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,3 @@ +--- +skip-changelog: + - head-branch: ['^release-*', 'release'] diff --git a/.github/workflows/build_container.yml b/.github/workflows/build_container.yml new file mode 100644 index 0000000..3f14b86 --- /dev/null +++ b/.github/workflows/build_container.yml @@ -0,0 +1,47 @@ +--- +name: Build and publish a 🛢️ container + +on: + push: + branches: + - 'main' + tags: + - '*' + workflow_dispatch: + +jobs: + setup-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Source checkout + uses: actions/checkout@v4 + + - id: set-matrix + run: echo "matrix=$(jq -c . build_versions.json)" >> $GITHUB_OUTPUT + + build-and-push-container: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + needs: setup-matrix + strategy: + matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }} + steps: + - name: Build Ruby Container ${{ matrix.full }}-${{ matrix.os }} + uses: voxpupuli/gha-build-and-publish-a-container@v2 + with: + registry_password: ${{ secrets.GITHUB_TOKEN }} + build_arch: linux/amd64,linux/arm64 + build_context: ${{ matrix.minor }}/${{ matrix.os }} + tags: | + ghcr.io/betadots/ruby:${{ matrix.major }} + ghcr.io/betadots/ruby:${{ matrix.minor }} + ghcr.io/betadots/ruby:${{ matrix.full }} + ghcr.io/betadots/ruby:${{ matrix.major }}-${{ matrix.os }} + ghcr.io/betadots/ruby:${{ matrix.minor }}-${{ matrix.os }} + ghcr.io/betadots/ruby:${{ matrix.full }}-${{ matrix.os }} + ghcr.io/betadots/ruby:${{ matrix.os }} + ghcr.io/betadots/ruby:latest diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..128d805 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,59 @@ +--- +name: QA🚦 + +on: + pull_request: {} + push: + branches: + - main + +jobs: + setup-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Source checkout + uses: actions/checkout@v4 + + - id: set-matrix + run: echo "matrix=$(jq -c . build_versions.json)" >> $GITHUB_OUTPUT + + build_test_container: + name: 'Build test container' + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + needs: setup-matrix + strategy: + matrix: ${{ fromJson(needs.setup-matrix.outputs.matrix) }} + steps: + - name: Test Ruby Container ${{ matrix.full }}-${{ matrix.os }} + uses: voxpupuli/gha-build-and-publish-a-container@v2 + with: + registry_password: ${{ secrets.GITHUB_TOKEN }} + publish: 'false' + build_context: ${{ matrix.minor }}/${{ matrix.os }} + tags: 'ci/ruby:${{ github.sha }}' + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: 'ci/ruby:${{ github.sha }}' + format: 'sarif' + output: 'trivy-results.sarif' + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: 'trivy-results.sarif' + + tests: + needs: + - build_test_container + runs-on: ubuntu-latest + name: Test suite + steps: + - run: echo Test suite completed diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml new file mode 100644 index 0000000..c708d34 --- /dev/null +++ b/.github/workflows/labeler.yml @@ -0,0 +1,14 @@ +--- +name: "Pull Request Labeler" + +on: + pull_request_target: {} + +jobs: + labeler: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v5 diff --git a/3.3/jammy/Dockerfile b/3.3/jammy/Dockerfile new file mode 100644 index 0000000..5e73f36 --- /dev/null +++ b/3.3/jammy/Dockerfile @@ -0,0 +1,125 @@ +# +# Fork of https://github.com/docker-library/ruby/blob/master/3.3/bookworm/Dockerfile +# + +FROM buildpack-deps:jammy + +# skip installing gem documentation +RUN set -eux; \ + mkdir -p /usr/local/etc; \ + { \ + echo 'install: --no-document'; \ + echo 'update: --no-document'; \ + } >> /usr/local/etc/gemrc + +ENV LANG C.UTF-8 + +# https://www.ruby-lang.org/en/news/2023/12/25/ruby-3-3-0-released/ +ENV RUBY_VERSION 3.3.0 +ENV RUBY_DOWNLOAD_URL https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.0.tar.xz +ENV RUBY_DOWNLOAD_SHA256 676b65a36e637e90f982b57b059189b3276b9045034dcd186a7e9078847b975b + +# some of ruby's build scripts are written in ruby +# we purge system ruby later to make sure our final image uses what we just built +RUN set -eux; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + dpkg-dev \ + libgdbm-dev \ + ruby \ + ; \ + rm -rf /var/lib/apt/lists/*; \ + \ + rustArch=; \ + dpkgArch="$(dpkg --print-architecture)"; \ + case "$dpkgArch" in \ + 'amd64') rustArch='x86_64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.26.0/x86_64-unknown-linux-gnu/rustup-init'; rustupSha256='0b2f6c8f85a3d02fde2efc0ced4657869d73fccfce59defb4e8d29233116e6db' ;; \ + 'arm64') rustArch='aarch64-unknown-linux-gnu'; rustupUrl='https://static.rust-lang.org/rustup/archive/1.26.0/aarch64-unknown-linux-gnu/rustup-init'; rustupSha256='673e336c81c65e6b16dcdede33f4cc9ed0f08bde1dbe7a935f113605292dc800' ;; \ + esac; \ + \ + if [ -n "$rustArch" ]; then \ + mkdir -p /tmp/rust; \ + \ + wget -O /tmp/rust/rustup-init "$rustupUrl"; \ + echo "$rustupSha256 */tmp/rust/rustup-init" | sha256sum --check --strict; \ + chmod +x /tmp/rust/rustup-init; \ + \ + export RUSTUP_HOME='/tmp/rust/rustup' CARGO_HOME='/tmp/rust/cargo'; \ + export PATH="$CARGO_HOME/bin:$PATH"; \ + /tmp/rust/rustup-init -y --no-modify-path --profile minimal --default-toolchain '1.74.1' --default-host "$rustArch"; \ + \ + rustc --version; \ + cargo --version; \ + fi; \ + \ + wget -O ruby.tar.xz "$RUBY_DOWNLOAD_URL"; \ + echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.xz" | sha256sum --check --strict; \ + \ + mkdir -p /usr/src/ruby; \ + tar -xJf ruby.tar.xz -C /usr/src/ruby --strip-components=1; \ + rm ruby.tar.xz; \ + \ + cd /usr/src/ruby; \ + \ +# hack in "ENABLE_PATH_CHECK" disabling to suppress: +# warning: Insecure world writable dir + { \ + echo '#define ENABLE_PATH_CHECK 0'; \ + echo; \ + cat file.c; \ + } > file.c.new; \ + mv file.c.new file.c; \ + \ + # workaround crash on arm64 + # https://bugs.ruby-lang.org/issues/20085 + # https://github.com/ruby/ruby/pull/9385 <- https://github.com/ruby/ruby/pull/9371 + wget -O 'arm64-fix.patch' 'https://github.com/ruby/ruby/commit/7f97e3540ce448b501bcbee15afac5f94bb22dd9.patch?full_index=1'; \ + echo '86bc65415fd62cb2272a4df249f39fb79db15617ad05c540e05a22f02eae73b3 *arm64-fix.patch' | sha256sum --check --strict; \ + patch -p1 -i arm64-fix.patch; \ + rm arm64-fix.patch; \ + \ + autoconf; \ + gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ + ./configure \ + --build="$gnuArch" \ + --disable-install-doc \ + --enable-shared \ + ${rustArch:+--enable-yjit} \ + ; \ + make -j "$(nproc)"; \ + make install; \ + \ + rm -rf /tmp/rust; \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark > /dev/null; \ + find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \ + | sort -u \ + | xargs -r dpkg-query --search \ + | cut -d: -f1 \ + | sort -u \ + | xargs -r apt-mark manual \ + ; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ + cd /; \ + rm -r /usr/src/ruby; \ +# verify we have no "ruby" packages installed + if dpkg -l | grep -i ruby; then exit 1; fi; \ + [ "$(command -v ruby)" = '/usr/local/bin/ruby' ]; \ +# rough smoke test + ruby --version; \ + gem --version; \ + bundle --version + +# don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $GEM_HOME/bin:$PATH +# adjust permissions of a few directories for running "gem install" as an arbitrary user +RUN mkdir -p "$GEM_HOME" && chmod 1777 "$GEM_HOME" + +CMD [ "irb" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..4445ae5 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Ruby container based on ubuntu + +this is mainly a fork of https://github.com/docker-library/ruby + +only change is: + +From + +```shell +FROM buildpack-deps:bookworm +``` + +to + +```shell +FROM buildpack-deps:jammy +``` diff --git a/build_versions.json b/build_versions.json new file mode 100644 index 0000000..6ac5cd4 --- /dev/null +++ b/build_versions.json @@ -0,0 +1,10 @@ +{ + "include": [ + { + "major": "3", + "minor": "3.3", + "full": "3.3.0", + "os": "jammy" + } + ] +}