v2.31.0-dev13 0d280f4

README.md RawHistoryFolder

Gordon Deploy Action

Build and push container images to a Gordon registry, with automatic deployment on push.

Features

  • Automatic image building from Dockerfile
  • Tag-based versioning (uses git tag as image tag)
  • Optional :latest tag pushing
  • Multi-platform builds support
  • Build caching with GitHub Actions cache
  • Works with Gordon's token and password authentication

Usage

Basic Usage (Tag Push)

name: Deploy to Gordon

on:
  push:
    tags:
      - 'v*'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Deploy to Gordon
        uses: bnema/gordon/.github/actions/deploy@main
        with:
          registry: registry.mydomain.com
          username: ${{ secrets.GORDON_USERNAME }}
          password: ${{ secrets.GORDON_TOKEN }}

Full Example with All Options

name: Deploy to Gordon

on:
  push:
    tags:
      - 'v*'
      - 'release-*'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Deploy to Gordon
        id: deploy
        uses: bnema/gordon/.github/actions/deploy@main
        with:
          registry: registry.mydomain.com
          username: ${{ secrets.GORDON_USERNAME }}
          password: ${{ secrets.GORDON_TOKEN }}
          image: myapp                    # Custom image name
          dockerfile: ./docker/Dockerfile # Custom Dockerfile path
          context: .                      # Build context
          build-args: |                   # Build arguments
            NODE_ENV=production
            API_URL=https://api.example.com
          platforms: linux/amd64,linux/arm64  # Multi-platform
          push-latest: 'true'             # Also push :latest

      - name: Print outputs
        run: |
          echo "Image: ${{ steps.deploy.outputs.image }}"
          echo "Tag: ${{ steps.deploy.outputs.tag }}"
          echo "Digest: ${{ steps.deploy.outputs.digest }}"

Inputs

Input Description Required Default
registry Gordon registry URL (e.g., registry.mydomain.com) Yes -
username Registry username (token subject for token auth) Yes -
password Registry password or token Yes -
image Image name No Repository name
tag Override image tag No Git tag or short SHA
dockerfile Path to Dockerfile No ./Dockerfile
context Build context path No .
build-args Build arguments (one per line) No -
platforms Target platforms No -
push-latest Also push with :latest tag No true
cache-from Cache source No type=gha
cache-to Cache destination No type=gha,mode=max

Outputs

Output Description
image Full image reference that was pushed
tag Tag that was pushed
digest Image digest

Authentication Setup

1. Generate a Gordon Token

On your Gordon server:

# Generate a never-expiring token for CI
gordon auth token generate --subject github-actions --scopes push,pull --expiry 0

2. Add GitHub Secrets

In your repository settings, add:

  • GORDON_USERNAME: The token subject (e.g., github-actions)
  • GORDON_TOKEN: The generated JWT token

3. Configure Gordon

Ensure your Gordon config has authentication enabled:

[auth]
enabled = true
secrets_backend = "pass"  # or "sops"
token_secret = "gordon/auth/token_secret"

Examples

Deploy on Tag + Manual Trigger

name: Deploy

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag to deploy'
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.event.inputs.tag || github.ref }}

      - uses: bnema/gordon/.github/actions/deploy@main
        with:
          registry: registry.mydomain.com
          username: ${{ secrets.GORDON_USERNAME }}
          password: ${{ secrets.GORDON_TOKEN }}
          tag: ${{ github.event.inputs.tag }}

Monorepo with Multiple Services

name: Deploy Services

on:
  push:
    tags:
      - 'v*'

jobs:
  deploy-api:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: bnema/gordon/.github/actions/deploy@main
        with:
          registry: registry.mydomain.com
          username: ${{ secrets.GORDON_USERNAME }}
          password: ${{ secrets.GORDON_TOKEN }}
          image: myapp-api
          dockerfile: ./services/api/Dockerfile
          context: ./services/api

  deploy-web:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: bnema/gordon/.github/actions/deploy@main
        with:
          registry: registry.mydomain.com
          username: ${{ secrets.GORDON_USERNAME }}
          password: ${{ secrets.GORDON_TOKEN }}
          image: myapp-web
          dockerfile: ./services/web/Dockerfile
          context: ./services/web

Build with Secrets (BuildKit)

- uses: bnema/gordon/.github/actions/deploy@main
  with:
    registry: registry.mydomain.com
    username: ${{ secrets.GORDON_USERNAME }}
    password: ${{ secrets.GORDON_TOKEN }}
    build-args: |
      NPM_TOKEN=${{ secrets.NPM_TOKEN }}

Troubleshooting

Authentication Failed

  • Verify your token hasn't been revoked: gordon auth token list
  • Ensure the token has push scope
  • Check that token_secret matches between token generation and validation

Dockerfile Not Found

  • Verify the dockerfile input path is correct
  • Paths are relative to the repository root

Push Failed

  • Ensure your Gordon server is accessible from GitHub Actions
  • Check firewall rules allow connections from GitHub's IP ranges
  • Verify the registry domain resolves correctly

Security Notes

  • Never commit tokens or passwords to your repository
  • Use GitHub Secrets for all sensitive values
  • Consider using short-lived tokens for production
  • Each Gordon instance has unique tokens (tokens from one instance won't work on another)
source
1# Gordon Deploy Action
2
3Build and push container images to a Gordon registry, with automatic deployment on push.
4
5## Features
6
7- Automatic image building from Dockerfile
8- Tag-based versioning (uses git tag as image tag)
9- Optional `:latest` tag pushing
10- Multi-platform builds support
11- Build caching with GitHub Actions cache
12- Works with Gordon's token and password authentication
13
14## Usage
15
16### Basic Usage (Tag Push)
17
18```yaml
19name: Deploy to Gordon
20
21on:
22  push:
23    tags:
24      - 'v*'
25
26jobs:
27  deploy:
28    runs-on: ubuntu-latest
29    steps:
30      - uses: actions/checkout@v6
31
32      - name: Deploy to Gordon
33        uses: bnema/gordon/.github/actions/deploy@main
34        with:
35          registry: registry.mydomain.com
36          username: ${{ secrets.GORDON_USERNAME }}
37          password: ${{ secrets.GORDON_TOKEN }}
38```
39
40### Full Example with All Options
41
42```yaml
43name: Deploy to Gordon
44
45on:
46  push:
47    tags:
48      - 'v*'
49      - 'release-*'
50
51jobs:
52  deploy:
53    runs-on: ubuntu-latest
54    steps:
55      - uses: actions/checkout@v6
56
57      - name: Deploy to Gordon
58        id: deploy
59        uses: bnema/gordon/.github/actions/deploy@main
60        with:
61          registry: registry.mydomain.com
62          username: ${{ secrets.GORDON_USERNAME }}
63          password: ${{ secrets.GORDON_TOKEN }}
64          image: myapp                    # Custom image name
65          dockerfile: ./docker/Dockerfile # Custom Dockerfile path
66          context: .                      # Build context
67          build-args: |                   # Build arguments
68            NODE_ENV=production
69            API_URL=https://api.example.com
70          platforms: linux/amd64,linux/arm64  # Multi-platform
71          push-latest: 'true'             # Also push :latest
72
73      - name: Print outputs
74        run: |
75          echo "Image: ${{ steps.deploy.outputs.image }}"
76          echo "Tag: ${{ steps.deploy.outputs.tag }}"
77          echo "Digest: ${{ steps.deploy.outputs.digest }}"
78```
79
80## Inputs
81
82| Input | Description | Required | Default |
83|-------|-------------|----------|---------|
84| `registry` | Gordon registry URL (e.g., `registry.mydomain.com`) | Yes | - |
85| `username` | Registry username (token subject for token auth) | Yes | - |
86| `password` | Registry password or token | Yes | - |
87| `image` | Image name | No | Repository name |
88| `tag` | Override image tag | No | Git tag or short SHA |
89| `dockerfile` | Path to Dockerfile | No | `./Dockerfile` |
90| `context` | Build context path | No | `.` |
91| `build-args` | Build arguments (one per line) | No | - |
92| `platforms` | Target platforms | No | - |
93| `push-latest` | Also push with `:latest` tag | No | `true` |
94| `cache-from` | Cache source | No | `type=gha` |
95| `cache-to` | Cache destination | No | `type=gha,mode=max` |
96
97## Outputs
98
99| Output | Description |
100|--------|-------------|
101| `image` | Full image reference that was pushed |
102| `tag` | Tag that was pushed |
103| `digest` | Image digest |
104
105## Authentication Setup
106
107### 1. Generate a Gordon Token
108
109On your Gordon server:
110
111```bash
112# Generate a never-expiring token for CI
113gordon auth token generate --subject github-actions --scopes push,pull --expiry 0
114```
115
116### 2. Add GitHub Secrets
117
118In your repository settings, add:
119
120- `GORDON_USERNAME`: The token subject (e.g., `github-actions`)
121- `GORDON_TOKEN`: The generated JWT token
122
123### 3. Configure Gordon
124
125Ensure your Gordon config has authentication enabled:
126
127```toml
128[auth]
129enabled = true
130secrets_backend = "pass"  # or "sops"
131token_secret = "gordon/auth/token_secret"
132```
133
134## Examples
135
136### Deploy on Tag + Manual Trigger
137
138```yaml
139name: Deploy
140
141on:
142  push:
143    tags:
144      - 'v*'
145  workflow_dispatch:
146    inputs:
147      tag:
148        description: 'Tag to deploy'
149        required: true
150
151jobs:
152  deploy:
153    runs-on: ubuntu-latest
154    steps:
155      - uses: actions/checkout@v6
156        with:
157          ref: ${{ github.event.inputs.tag || github.ref }}
158
159      - uses: bnema/gordon/.github/actions/deploy@main
160        with:
161          registry: registry.mydomain.com
162          username: ${{ secrets.GORDON_USERNAME }}
163          password: ${{ secrets.GORDON_TOKEN }}
164          tag: ${{ github.event.inputs.tag }}
165```
166
167### Monorepo with Multiple Services
168
169```yaml
170name: Deploy Services
171
172on:
173  push:
174    tags:
175      - 'v*'
176
177jobs:
178  deploy-api:
179    runs-on: ubuntu-latest
180    steps:
181      - uses: actions/checkout@v6
182      - uses: bnema/gordon/.github/actions/deploy@main
183        with:
184          registry: registry.mydomain.com
185          username: ${{ secrets.GORDON_USERNAME }}
186          password: ${{ secrets.GORDON_TOKEN }}
187          image: myapp-api
188          dockerfile: ./services/api/Dockerfile
189          context: ./services/api
190
191  deploy-web:
192    runs-on: ubuntu-latest
193    steps:
194      - uses: actions/checkout@v6
195      - uses: bnema/gordon/.github/actions/deploy@main
196        with:
197          registry: registry.mydomain.com
198          username: ${{ secrets.GORDON_USERNAME }}
199          password: ${{ secrets.GORDON_TOKEN }}
200          image: myapp-web
201          dockerfile: ./services/web/Dockerfile
202          context: ./services/web
203```
204
205### Build with Secrets (BuildKit)
206
207```yaml
208- uses: bnema/gordon/.github/actions/deploy@main
209  with:
210    registry: registry.mydomain.com
211    username: ${{ secrets.GORDON_USERNAME }}
212    password: ${{ secrets.GORDON_TOKEN }}
213    build-args: |
214      NPM_TOKEN=${{ secrets.NPM_TOKEN }}
215```
216
217## Troubleshooting
218
219### Authentication Failed
220
221- Verify your token hasn't been revoked: `gordon auth token list`
222- Ensure the token has `push` scope
223- Check that `token_secret` matches between token generation and validation
224
225### Dockerfile Not Found
226
227- Verify the `dockerfile` input path is correct
228- Paths are relative to the repository root
229
230### Push Failed
231
232- Ensure your Gordon server is accessible from GitHub Actions
233- Check firewall rules allow connections from GitHub's IP ranges
234- Verify the registry domain resolves correctly
235
236## Security Notes
237
238- Never commit tokens or passwords to your repository
239- Use GitHub Secrets for all sensitive values
240- Consider using short-lived tokens for production
241- Each Gordon instance has unique tokens (tokens from one instance won't work on another)

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close