Skip to content

Add Linux distribution support (Snap, APT, RPM) #66

@rianjs

Description

@rianjs

Summary

Add Linux distribution support for newrelic-cli (nrq) to match the distribution channels available in other Open CLI Collective tools (like confluence-cli). This includes:

  • Snap Store - Universal Linux package with automatic updates
  • APT repository - Debian/Ubuntu native package management
  • RPM repository - Fedora/RHEL/CentOS native package management
  • Direct .deb/.rpm downloads - Attached to GitHub releases

Reference

  • Guide: /Users/rianjs/dev/linux-distribution.md
  • Reference implementation: confluence-cli (PR #96)

Current State

The newrelic-cli already has:

  • GoReleaser building Linux binaries (amd64, arm64)
  • Homebrew tap distribution
  • Chocolatey distribution
  • Winget distribution
  • nfpms config for .deb/.rpm generation
  • Snap package setup
  • linux-packages repo integration
  • README Linux installation instructions

Tasks

Part 1: GoReleaser nfpms Configuration

  • Add nfpms section to .goreleaser.yml after the archives section:
# Linux packages (.deb and .rpm)
nfpms:
  - id: nrq
    package_name: nrq
    vendor: Open CLI Collective
    homepage: https://github.com/open-cli-collective/newrelic-cli
    maintainer: Open CLI Collective <https://github.com/open-cli-collective>
    description: Command-line interface for New Relic APIs
    license: MIT
    formats:
      - deb
      - rpm
    bindir: /usr/bin
    contents:
      - src: LICENSE
        dst: /usr/share/licenses/nrq/LICENSE
  • Test locally:
    goreleaser check
    goreleaser build --snapshot --clean
    ls dist/*.deb dist/*.rpm

Part 2: Snap Package Setup

  • Check snap name availability at https://snapcraft.io (try nrq first, fallback to ocli-newrelic)

  • Register the snap name:

    snapcraft login
    snapcraft register <snap-name>
  • Create snap/snapcraft.yaml:

name: <snap-name>  # nrq or ocli-newrelic
base: core22
version: git
summary: Command-line interface for New Relic APIs
description: |
  nrq is a CLI for interacting with New Relic APIs.

  Features:
  - APM applications, alerts, and dashboards
  - Deployment markers and entity search
  - NRQL and NerdGraph queries
  - Log parsing rules and synthetic monitors
  - Table, JSON, and plain output formats

  Run 'nrq config set-api-key' to configure credentials.

grade: stable
confinement: strict

architectures:
  - build-on: amd64
  - build-on: arm64

plugs:
  dot-config-newrelic-cli:
    interface: personal-files
    read:
      - $HOME/.config/newrelic-cli
    write:
      - $HOME/.config/newrelic-cli

apps:
  <snap-name>:
    command: bin/nrq
    plugs:
      - home
      - network
      - dot-config-newrelic-cli
    aliases:
      - nrq  # Only needed if snap-name != nrq

parts:
  nrq:
    plugin: go
    source: .
    build-snaps:
      - go/1.24/stable
    build-environment:
      - CGO_ENABLED: "0"
    override-build: |
      # Get version from git
      VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev")
      COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
      DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

      # Build with ldflags
      go build -o $SNAPCRAFT_PART_INSTALL/bin/nrq \
        -ldflags "-s -w \
          -X github.com/open-cli-collective/newrelic-cli/internal/version.Version=${VERSION} \
          -X github.com/open-cli-collective/newrelic-cli/internal/version.Commit=${COMMIT} \
          -X github.com/open-cli-collective/newrelic-cli/internal/version.BuildDate=${DATE}" \
        ./cmd/nrq
  • Export and store Snapcraft credentials:
    snapcraft export-login --snaps=<snap-name> --acls=package_upload /tmp/snapcraft-creds.txt
    gh secret set SNAPCRAFT_STORE_CREDENTIALS --repo open-cli-collective/newrelic-cli < /tmp/snapcraft-creds.txt
    rm /tmp/snapcraft-creds.txt

Part 3: linux-packages Repository Integration

  • Create a Personal Access Token (PAT):

    1. Go to https://github.com/settings/tokens
    2. Generate new token (classic)
    3. Name: linux-packages-dispatch-newrelic-cli
    4. Scopes: repo (full control of private repositories)
  • Add the dispatch token:

    gh secret set LINUX_PACKAGES_DISPATCH_TOKEN --repo open-cli-collective/newrelic-cli
  • Update linux-packages/README.md with new package entry:

    | `nrq` | Command-line interface for New Relic | [newrelic-cli](https://github.com/open-cli-collective/newrelic-cli) |

Part 4: Release Workflow Updates

  • Add snap job to .github/workflows/release.yml:
snap:
  needs: goreleaser
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Build snap
      uses: snapcore/action-build@v1
      id: build

    - name: Publish to Snapcraft Store
      uses: snapcore/action-publish@v1
      env:
        SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
      with:
        snap: ${{ steps.build.outputs.snap }}
        release: stable
  • Add linux-packages job to .github/workflows/release.yml:
linux-packages:
  needs: goreleaser
  runs-on: ubuntu-latest
  steps:
    - name: Trigger linux-packages repo update
      uses: peter-evans/repository-dispatch@v3
      with:
        token: ${{ secrets.LINUX_PACKAGES_DISPATCH_TOKEN }}
        repository: open-cli-collective/linux-packages
        event-type: package-release
        client-payload: |-
          {
            "package": "nrq",
            "version": "${{ github.ref_name }}",
            "repo": "open-cli-collective/newrelic-cli"
          }

Part 5: README Documentation

  • Add Linux installation section to README.md (after Windows section):
### Linux

**Snap (recommended)**

```bash
sudo snap install <snap-name>

APT (Debian/Ubuntu)

# Add the GPG key
curl -fsSL https://open-cli-collective.github.io/linux-packages/keys/gpg.asc | sudo gpg --dearmor -o /usr/share/keyrings/open-cli-collective.gpg

# Add the repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/open-cli-collective.gpg] https://open-cli-collective.github.io/linux-packages/apt stable main" | sudo tee /etc/apt/sources.list.d/open-cli-collective.list

# Install
sudo apt update
sudo apt install nrq

Note: This is our third-party APT repository, not official Debian/Ubuntu repos.

DNF/YUM (Fedora/RHEL/CentOS)

# Add the repository
sudo tee /etc/yum.repos.d/open-cli-collective.repo << 'EOF'
[open-cli-collective]
name=Open CLI Collective
baseurl=https://open-cli-collective.github.io/linux-packages/rpm
enabled=1
gpgcheck=1
gpgkey=https://open-cli-collective.github.io/linux-packages/keys/gpg.asc
EOF

# Install
sudo dnf install nrq

Note: This is our third-party RPM repository, not official Fedora/RHEL repos.

Binary download

Download .deb, .rpm, or .tar.gz from the Releases page.


### Part 6: Secrets Checklist

Required secrets for newrelic-cli repo:

| Secret | Purpose | Status |
|--------|---------|--------|
| `TAP_GITHUB_TOKEN` | Push to homebrew-tap | Already configured |
| `CHOCOLATEY_API_KEY` | Publish to Chocolatey | Already configured |
| `WINGET_GITHUB_TOKEN` | Submit to winget-pkgs | Already configured |
| `SNAPCRAFT_STORE_CREDENTIALS` | Publish to Snap Store | **Needs setup** |
| `LINUX_PACKAGES_DISPATCH_TOKEN` | Trigger linux-packages | **Needs setup** |

### Part 7: Testing & Verification

- [ ] Validate GoReleaser config: `goreleaser check`
- [ ] Test snap build locally (optional): `snapcraft --destructive-mode`
- [ ] Verify all secrets are configured: `gh secret list --repo open-cli-collective/newrelic-cli`

After first release:
- [ ] Check Snap Store at https://snapcraft.io/<snap-name>
- [ ] Test APT installation in Docker
- [ ] Test RPM installation in Docker

## Files to Create/Modify

| File | Action | Description |
|------|--------|-------------|
| `.goreleaser.yml` | Modify | Add `nfpms` section |
| `snap/snapcraft.yaml` | Create | Snap package definition |
| `.github/workflows/release.yml` | Modify | Add `snap` and `linux-packages` jobs |
| `README.md` | Modify | Add Linux installation instructions |

## Key Details

- **Binary name:** `nrq`
- **Module path:** `github.com/open-cli-collective/newrelic-cli`
- **Version variables:** `internal/version.Version`, `internal/version.Commit`, `internal/version.BuildDate`
- **Config directory:** `~/.config/newrelic-cli/`

## Notes

The snap `personal-files` interface requires manual approval from Canonical. After the first snap is published, you may need to request a review at https://forum.snapcraft.io/c/store-requests/ if automatic connection is needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions