From 5f0ddc1901cc15935dbb21e90f5667efb8b40f77 Mon Sep 17 00:00:00 2001 From: tinqs-limited Date: Fri, 22 May 2026 17:52:08 +0100 Subject: [PATCH] feat: composite actions + runner base image Actions: checkout, setup-go, setup-node, setup-aws Runner image: Go 1.26 + Node 22 + AWS CLI + Docker (docker:29-dind) --- README.md | 42 ++++++++++++++++++++++++++++++-- checkout/action.yml | 50 ++++++++++++++++++++++++++++++++++++++ runner-image/Dockerfile | 36 +++++++++++++++++++++++++++ runner-image/build-push.sh | 21 ++++++++++++++++ setup-aws/action.yml | 41 +++++++++++++++++++++++++++++++ setup-go/action.yml | 30 +++++++++++++++++++++++ setup-node/action.yml | 39 +++++++++++++++++++++++++++++ 7 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 checkout/action.yml create mode 100644 runner-image/Dockerfile create mode 100644 runner-image/build-push.sh create mode 100644 setup-aws/action.yml create mode 100644 setup-go/action.yml create mode 100644 setup-node/action.yml diff --git a/README.md b/README.md index 3dbb882..9ae82e8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,41 @@ -# ci +# tinqs/ci -Tinqs CI - composite actions and runner base image \ No newline at end of file +Tinqs CI toolchain — composite Gitea Actions and runner base image. + +## Actions + +| Action | Description | Replaces | +|--------|-------------|----------| +| `tinqs/ci/checkout` | Clone a Gitea repo | `actions/checkout` | +| `tinqs/ci/setup-go` | Install Go | `actions/setup-go` | +| `tinqs/ci/setup-node` | Install Node.js + pnpm | `actions/setup-node` | +| `tinqs/ci/setup-aws` | Install AWS CLI + ECR login | — | + +### Usage + +```yaml +steps: + - uses: tinqs/ci/checkout@v1 + + - uses: tinqs/ci/setup-go@v1 + with: + go-version: '1.26.2' + + - uses: tinqs/ci/setup-node@v1 + with: + node-version: '22' + + - uses: tinqs/ci/setup-aws@v1 + with: + ecr-login: 'true' + ecr-repo: '149751500842.dkr.ecr.eu-west-1.amazonaws.com/tinqs-git' +``` + +## Runner Base Image + +`runner-image/` contains the Dockerfile for the CI runner container. Pre-installs Go, Node.js, AWS CLI, Docker, git, and ssh — no per-job install overhead. + +```bash +cd runner-image +./build-push.sh v1 +``` diff --git a/checkout/action.yml b/checkout/action.yml new file mode 100644 index 0000000..37b8eef --- /dev/null +++ b/checkout/action.yml @@ -0,0 +1,50 @@ +name: 'Tinqs Checkout' +description: 'Clone a Gitea repository (replaces actions/checkout)' + +inputs: + repository: + description: 'Repository (owner/repo)' + default: '${{ github.repository }}' + ref: + description: 'Branch or tag to checkout' + default: '${{ github.ref_name }}' + depth: + description: 'Clone depth (0 = full)' + default: '1' + path: + description: 'Directory to clone into' + default: '.' + token: + description: 'Gitea access token (for private repos)' + default: '' + +runs: + using: 'composite' + steps: + - run: | + REPO="${{ inputs.repository }}" + REF="${{ inputs.ref }}" + DEPTH="${{ inputs.depth }}" + TARGET="${{ inputs.path }}" + TOKEN="${{ inputs.token }}" + + if [ "$DEPTH" = "0" ]; then + DEPTH_FLAG="" + else + DEPTH_FLAG="--depth $DEPTH" + fi + + if [ -n "$TOKEN" ]; then + URL="https://token:${TOKEN}@tinqs.com/${REPO}.git" + else + URL="https://tinqs.com/${REPO}.git" + fi + + if [ "$TARGET" = "." ]; then + git clone $DEPTH_FLAG --branch "$REF" "$URL" . + else + git clone $DEPTH_FLAG --branch "$REF" "$URL" "$TARGET" + fi + + echo "Checked out ${REPO}@${REF}" + shell: bash diff --git a/runner-image/Dockerfile b/runner-image/Dockerfile new file mode 100644 index 0000000..ec85e3f --- /dev/null +++ b/runner-image/Dockerfile @@ -0,0 +1,36 @@ +# Tinqs CI Runner Base Image +# Pre-installed: Go, Node.js, AWS CLI, Docker CLI, git, ssh, curl +# Used by act_runner with runs-on: host (no per-job install overhead) + +FROM docker:29-dind + +ARG GO_VERSION=1.26.2 +ARG NODE_VERSION=22 + +# System packages +RUN apk add --no-cache \ + bash git curl wget unzip tar \ + ca-certificates openssh-client \ + build-base python3 \ + s6 tzdata + +# Go +RUN curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar -C /usr/local -xz +ENV PATH="/usr/local/go/bin:${PATH}" +ENV GOPATH="/go" +ENV PATH="${GOPATH}/bin:${PATH}" + +# Node.js + pnpm +RUN apk add --no-cache nodejs npm && \ + npm install -g pnpm + +# AWS CLI +RUN curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscli.zip && \ + unzip -q /tmp/awscli.zip -d /tmp && \ + /tmp/aws/install && \ + rm -rf /tmp/awscli.zip /tmp/aws + +# Verify +RUN go version && node --version && pnpm --version && aws --version && docker --version && git --version + +WORKDIR /workspace diff --git a/runner-image/build-push.sh b/runner-image/build-push.sh new file mode 100644 index 0000000..69d3f33 --- /dev/null +++ b/runner-image/build-push.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Build and push Tinqs CI runner base image to ECR +set -euo pipefail + +AWS_REGION="${AWS_REGION:-eu-west-1}" +ACCOUNT_ID="${ACCOUNT_ID:-149751500842}" +ECR_REPO="${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/tinqs-runner" +TAG="${1:-latest}" + +echo "Building tinqs-runner:${TAG}..." +docker build -t "${ECR_REPO}:${TAG}" -t "${ECR_REPO}:latest" . + +echo "Logging into ECR..." +aws ecr get-login-password --region "${AWS_REGION}" | \ + docker login --username AWS --password-stdin "${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com" + +echo "Pushing..." +docker push "${ECR_REPO}:${TAG}" +docker push "${ECR_REPO}:latest" + +echo "Done: ${ECR_REPO}:${TAG}" diff --git a/setup-aws/action.yml b/setup-aws/action.yml new file mode 100644 index 0000000..0cbaaa2 --- /dev/null +++ b/setup-aws/action.yml @@ -0,0 +1,41 @@ +name: 'Tinqs Setup AWS' +description: 'Install AWS CLI and optionally login to ECR' + +inputs: + region: + description: 'AWS region' + default: 'eu-west-1' + ecr-login: + description: 'Login to ECR (true/false)' + default: 'false' + ecr-repo: + description: 'ECR repository URL (required if ecr-login is true)' + default: '' + +runs: + using: 'composite' + steps: + - run: | + REGION="${{ inputs.region }}" + ECR_LOGIN="${{ inputs.ecr-login }}" + ECR_REPO="${{ inputs.ecr-repo }}" + + # Install AWS CLI if missing + if ! command -v aws &>/dev/null; then + echo "Installing AWS CLI..." + curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscli.zip + unzip -q /tmp/awscli.zip -d /tmp/aws-install + /tmp/aws-install/aws/install + rm -rf /tmp/awscli.zip /tmp/aws-install + fi + + aws --version + + # ECR login + if [ "$ECR_LOGIN" = "true" ] && [ -n "$ECR_REPO" ]; then + echo "Logging into ECR ($REGION)..." + aws ecr get-login-password --region "$REGION" | \ + docker login --username AWS --password-stdin "$ECR_REPO" + echo "ECR login OK" + fi + shell: bash diff --git a/setup-go/action.yml b/setup-go/action.yml new file mode 100644 index 0000000..3c5f6d0 --- /dev/null +++ b/setup-go/action.yml @@ -0,0 +1,30 @@ +name: 'Tinqs Setup Go' +description: 'Install Go and configure PATH (replaces actions/setup-go)' + +inputs: + go-version: + description: 'Go version to install' + default: '1.26.2' + +runs: + using: 'composite' + steps: + - run: | + GO_VERSION="${{ inputs.go-version }}" + + # Skip if already installed at correct version + if command -v go &>/dev/null; then + CURRENT=$(go version | grep -oP '\d+\.\d+\.\d+' || true) + if [ "$CURRENT" = "$GO_VERSION" ]; then + echo "Go $GO_VERSION already installed" + go version + exit 0 + fi + fi + + echo "Installing Go $GO_VERSION..." + curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" | tar -C /usr/local -xz + echo "/usr/local/go/bin" >> "$GITHUB_PATH" + export PATH="/usr/local/go/bin:$PATH" + go version + shell: bash diff --git a/setup-node/action.yml b/setup-node/action.yml new file mode 100644 index 0000000..3e51eef --- /dev/null +++ b/setup-node/action.yml @@ -0,0 +1,39 @@ +name: 'Tinqs Setup Node' +description: 'Install Node.js and pnpm (replaces actions/setup-node)' + +inputs: + node-version: + description: 'Node.js major version' + default: '22' + pnpm: + description: 'Install pnpm (true/false)' + default: 'true' + +runs: + using: 'composite' + steps: + - run: | + NODE_VERSION="${{ inputs.node-version }}" + INSTALL_PNPM="${{ inputs.pnpm }}" + + # Skip if already installed at correct major version + if command -v node &>/dev/null; then + CURRENT=$(node --version | grep -oP '\d+' | head -1) + if [ "$CURRENT" = "$NODE_VERSION" ]; then + echo "Node $NODE_VERSION already installed" + node --version + [ "$INSTALL_PNPM" = "true" ] && command -v pnpm &>/dev/null && pnpm --version && exit 0 + fi + fi + + echo "Installing Node.js $NODE_VERSION..." + curl -fsSL "https://deb.nodesource.com/setup_${NODE_VERSION}.x" | bash - + apt-get install -y nodejs + + if [ "$INSTALL_PNPM" = "true" ]; then + npm install -g pnpm + pnpm --version + fi + + node --version + shell: bash