From 503f7b2c1d4b9fbbfce82ccf22ed4980fc9f414f Mon Sep 17 00:00:00 2001 From: John Ajera <37360952+jajera@users.noreply.github.com> Date: Mon, 1 Dec 2025 12:01:39 +0000 Subject: [PATCH] feat: initial commit first release --- .dockerignore | 7 ++ .github/dependabot.yml | 26 +++++++ .github/workflows/auto-merge.yml | 26 +++++++ .github/workflows/build-and-release.yml | 65 +++++++++++++++++ .github/workflows/ci.yml | 31 ++++++++ .github/workflows/commitmsg-conform.yml | 11 +++ .github/workflows/markdown-lint.yml | 14 ++++ .vscode/extensions.json | 20 ++++++ .vscode/settings.json | 93 ++++++++++++++++++++++++ Dockerfile | 47 ++++++++++++ README.md | 95 ++++++++++++++++++++++++- 11 files changed, 434 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/auto-merge.yml create mode 100644 .github/workflows/build-and-release.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/commitmsg-conform.yml create mode 100644 .github/workflows/markdown-lint.yml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..03e3da7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +.git +.github +README.md +LICENSE +*.md +.vscode +.gitignore diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..968353a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: + # Monitor Docker base image + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "chore" + include: "scope" + ignore: + # Block major version updates for Alpine (e.g., 3.18 -> 3.19) + # Allow only patch and minor updates within the same major version + - dependency-name: "alpine" + update-types: ["version-update:semver-major"] + + # Monitor GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + commit-message: + prefix: "chore" + include: "scope" diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 0000000..12a5e6f --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,26 @@ +name: Auto-merge Dependabot PRs + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + check_suite: + types: [completed] + +permissions: + contents: write + pull-requests: write + checks: read + +jobs: + auto-merge: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - name: Enable auto-merge for Dependabot PRs + uses: fastify/github-action-merge-dependabot@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + target: main + merge-method: squash + use-github-auto-merge: true + skip-verification: false diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml new file mode 100644 index 0000000..04da5a4 --- /dev/null +++ b/.github/workflows/build-and-release.yml @@ -0,0 +1,65 @@ +name: Build and Release + +on: + push: + branches: + - main + tags: + - "v*" + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Create Release + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v2 + with: + files: "" + generate_release_notes: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7ca9832 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v5 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: false + tags: slinktool-image:test + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Test Docker image + run: | + docker run --rm slinktool-image:test -V || docker run --rm slinktool-image:test -h || true diff --git a/.github/workflows/commitmsg-conform.yml b/.github/workflows/commitmsg-conform.yml new file mode 100644 index 0000000..8af1d71 --- /dev/null +++ b/.github/workflows/commitmsg-conform.yml @@ -0,0 +1,11 @@ +name: Commit Message Conformance +on: + pull_request: {} +permissions: + statuses: write + checks: write + contents: read + pull-requests: read +jobs: + commitmsg-conform: + uses: actionsforge/actions/.github/workflows/commitmsg-conform.yml@main diff --git a/.github/workflows/markdown-lint.yml b/.github/workflows/markdown-lint.yml new file mode 100644 index 0000000..034b809 --- /dev/null +++ b/.github/workflows/markdown-lint.yml @@ -0,0 +1,14 @@ +name: Markdown Lint + +on: + pull_request: {} + +permissions: + statuses: write + checks: write + contents: read + pull-requests: read + +jobs: + markdown-lint: + uses: actionsforge/actions/.github/workflows/markdown-lint.yml@main diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..6336ed3 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,20 @@ +{ + "recommendations": [ + "amazonwebservices.aws-toolkit-vscode", + "davidanson.vscode-markdownlint", + "eamodio.gitlens", + "esbenp.prettier-vscode", + "foxundermoon.shell-format", + "Gruntfuggly.todo-tree", + "hashicorp.terraform", + "mhutchie.git-graph", + "ms-vscode-remote.remote-ssh-edit", + "ms-vscode-remote.remote-ssh", + "ms-vscode.remote-containers", + "ms-vscode.vscode-json", + "redhat.vscode-yaml", + "streetsidesoftware.code-spell-checker", + "usernamehw.errorlens", + "vscode-icons-team.vscode-icons" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..beeafba --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,93 @@ +{ + "files.associations": { + "*.tf": "terraform", + "*.tfvars": "terraform", + "*.tfstate": "json", + "*.tfstate.backup": "json", + "*.hcl": "terraform", + "*.nomad": "hcl", + "*.consul": "hcl", + "*.vault": "hcl", + "*.dockerfile": "dockerfile", + "*.sh.tpl": "shellscript", + "docker-compose*.yml": "yaml", + "Dockerfile*": "dockerfile" + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/.terraform": true, + "**/.terraform.lock.hcl": true, + "**/terraform.tfstate*": true, + "**/.terraform.tfstate.lock.info": true, + "__debug_bin": true, + "vendor/": true, + "go.sum": true + }, + "files.trimTrailingWhitespace": true, + "files.trimFinalNewlines": true, + "files.insertFinalNewline": true, + "files.autoSave": "onFocusChange", + "search.exclude": { + "**/.terraform": true, + "**/terraform.tfstate*": true, + "**/.terraform.tfstate.lock.info": true + }, + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "editor.rulers": [80, 120], + "editor.wordWrap": "wordWrapColumn", + "editor.wordWrapColumn": 120, + "editor.tabSize": 2, + "editor.insertSpaces": true, + "editor.detectIndentation": false, + "workbench.iconTheme": "vscode-icons", + "workbench.colorTheme": "Default Dark+", + "terraform.codelens.referenceCount": true, + "[terraform]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "hashicorp.terraform", + "editor.tabSize": 2, + "editor.insertSpaces": true, + "editor.detectIndentation": false, + "editor.rulers": [80, 120], + "editor.wordWrap": "wordWrapColumn", + "editor.wordWrapColumn": 120 + }, + "[hcl]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "hashicorp.terraform", + "editor.tabSize": 2, + "editor.insertSpaces": true, + "editor.detectIndentation": false + }, + "[json]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.tabSize": 2, + "editor.insertSpaces": true + }, + "[yaml]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "redhat.vscode-yaml", + "editor.tabSize": 2, + "editor.insertSpaces": true + }, + "[shellscript]": { + "editor.defaultFormatter": "foxundermoon.shell-format", + "editor.tabSize": 2, + "editor.insertSpaces": true + }, + "[markdown]": { + "editor.defaultFormatter": "davidanson.vscode-markdownlint", + "editor.tabSize": 2, + "editor.insertSpaces": true, + "editor.wordWrap": "on" + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4695e09 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,47 @@ +# Multi-stage build for slinktool +# Stage 1: Build slinktool +FROM alpine:latest AS builder + +# Install build dependencies +RUN apk add --no-cache \ + build-base \ + git \ + make \ + gcc \ + musl-dev + +# Clone and build slinktool +WORKDIR /build +RUN git clone https://github.com/EarthScope/slinktool.git . && \ + make + +# Install slinktool binary to /usr/local/bin +# The binary should be in the current directory after make +RUN if [ -f ./slinktool ]; then \ + install -m 755 ./slinktool /usr/local/bin/slinktool; \ + else \ + find . -name "slinktool" -type f -executable -exec install -m 755 {} /usr/local/bin/slinktool \; && \ + test -f /usr/local/bin/slinktool || (echo "ERROR: slinktool binary not found after build" && find . -type f && exit 1); \ + fi + +# Stage 2: Runtime image +FROM alpine:latest + +# Install runtime dependencies (minimal - just what's needed to run) +# Note: If slinktool is statically linked, these may not be needed +# but ca-certificates is useful for HTTPS connections +RUN apk add --no-cache \ + ca-certificates + +# Copy the slinktool binary from builder +COPY --from=builder /usr/local/bin/slinktool /usr/local/bin/slinktool + +# Verify the binary exists and is executable +RUN test -f /usr/local/bin/slinktool && /usr/local/bin/slinktool -V || true + +# Set slinktool as the entrypoint +ENTRYPOINT ["slinktool"] + +# Default command (can be overridden) +# slinktool requires arguments, so we'll just set the entrypoint +# Users should provide their own command arguments diff --git a/README.md b/README.md index 1fda772..c003ddd 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,95 @@ # slinktool-image -Docker image for slinktool, a command-line utility to query and retrieve seismic waveform data from SeedLink and FDSN data centers + +Docker image for slinktool, a command-line utility to query and retrieve seismic waveform data from SeedLink and FDSN data centers. + +## Overview + +This repository contains a containerized version of the [slinktool](https://github.com/EarthScope/slinktool) CLI tool. The image is built from source and published to GitHub Container Registry (GHCR) for easy deployment and use. + +## Quick Start + +### Pull and Run + +```bash +docker pull ghcr.io/platformfuzz/slinktool-image:latest +docker run --rm ghcr.io/platformfuzz/slinktool-image:latest -V +``` + +### Example Usage + +```bash +# Check version +docker run --rm ghcr.io/platformfuzz/slinktool-image:latest -V + +# Query a SeedLink server +docker run --rm ghcr.io/platformfuzz/slinktool-image:latest \ + -S your-server:18000 \ + -s "NET_STA" \ + -b 2024-01-01T00:00:00 \ + -e 2024-01-01T01:00:00 +``` + +## Build Locally + +### Prerequisites + +- Docker + +### Build Instructions + +```bash +# Clone the repository +git clone https://github.com/platformfuzz/slinktool-image.git +cd slinktool-image + +# Build the image +docker build -t slinktool-image:local . + +# Test the image +docker run --rm slinktool-image:local -V +``` + +## CI/CD + +This repository includes GitHub Actions workflows that: + +- **CI Workflow** (`.github/workflows/ci.yml`): + - Runs on pull requests + - Builds the Docker image + - Tests that slinktool is accessible + +- **Build and Release Workflow** (`.github/workflows/build-and-release.yml`): + - Runs on pushes to `main` branch + - Builds and pushes to `ghcr.io/platformfuzz/slinktool-image:latest` + - On version tags (e.g., `v1.0.0`), creates a tagged release + - Supports semantic versioning with multiple tag patterns + +Images are available at: `ghcr.io/platformfuzz/slinktool-image` + +## Image Details + +- **Base Image:** Alpine Linux (minimal size) +- **Build Strategy:** Multi-stage build for optimal image size +- **Entrypoint:** `slinktool` +- **Source:** Built from [EarthScope/slinktool](https://github.com/EarthScope/slinktool) + +## Project Structure + +```text +slinktool-image/ +├── Dockerfile # Multi-stage build definition +├── .github/ +│ └── workflows/ +│ ├── ci.yml # CI workflow for PRs +│ └── build-and-release.yml # CI/CD to build and push to GHCR +├── .dockerignore # Files to exclude from build context +└── README.md +``` + +## License + +MIT License - see LICENSE file for details. + +## Related Projects + +- [slinktool](https://github.com/EarthScope/slinktool) - Source repository for the slinktool CLI