grain.social is a photo sharing platform built on atproto.
1name: Release CLI Binaries
2
3on:
4 push:
5 tags:
6 - 'cli@*'
7 workflow_dispatch:
8 inputs:
9 tag:
10 description: 'Tag to release (e.g. cli@1.0.0)'
11 required: true
12 type: string
13
14permissions:
15 contents: write
16
17jobs:
18 build:
19 name: Build CLI Binaries
20 strategy:
21 matrix:
22 include:
23 # - target: x86_64-unknown-linux-gnu
24 # os: ubuntu-latest
25 # package: grain-linux-x86_64
26 # artifact: grain-linux-x86_64
27 # - target: aarch64-unknown-linux-gnu
28 # os: ubuntu-latest
29 # package: grain-linux-aarch64
30 # artifact: grain-linux-aarch64
31 # - target: x86_64-apple-darwin
32 # os: macos-13 # Intel Mac
33 # package: grain-macos-x86_64
34 # artifact: grain-darwin-x86_64
35 - target: aarch64-apple-darwin
36 os: macos-latest # Apple Silicon Mac
37 package: grain-macos-aarch64
38 artifact: grain-darwin-aarch64
39 # - target: x86_64-pc-windows-gnu
40 # os: ubuntu-latest
41 # package: grain-windows-x86_64
42 # artifact: grain-windows-x86_64.exe
43
44 runs-on: ${{ matrix.os }}
45 defaults:
46 run:
47 working-directory: cli
48
49 steps:
50 - name: Checkout
51 uses: actions/checkout@v4
52
53 - name: Install Nix
54 uses: DeterminateSystems/nix-installer-action@main
55 with:
56 logger: pretty
57
58 - name: Setup Nix cache
59 uses: DeterminateSystems/magic-nix-cache-action@main
60
61 - name: Check flake
62 run: nix flake check
63
64 - name: Build ${{ matrix.target }}
65 run: nix build .#${{ matrix.package }}
66
67 - name: Copy binary
68 run: |
69 mkdir -p releases
70 if [ "${{ matrix.target }}" == "x86_64-pc-windows-gnu" ]; then
71 cp result/bin/grain.exe releases/${{ matrix.artifact }}
72 else
73 cp result/bin/grain releases/${{ matrix.artifact }}
74 fi
75
76 - name: Upload artifact
77 uses: actions/upload-artifact@v4
78 with:
79 name: ${{ matrix.artifact }}
80 path: cli/releases/${{ matrix.artifact }}
81 retention-days: 7
82
83 release:
84 name: Create Release
85 needs: build
86 runs-on: ubuntu-latest
87 steps:
88 - name: Checkout
89 uses: actions/checkout@v4
90
91 - name: Download all artifacts
92 uses: actions/download-artifact@v4
93 with:
94 path: artifacts
95
96 - name: Prepare release assets
97 run: |
98 mkdir -p release-assets
99
100 # Copy all binaries
101 for dir in artifacts/*/; do
102 for file in "$dir"*; do
103 if [ -f "$file" ]; then
104 cp "$file" release-assets/
105 fi
106 done
107 done
108
109 # Copy install script
110 cp cli/install.sh release-assets/
111
112 # Create checksums
113 cd release-assets
114 sha256sum * > checksums.txt
115
116 # List files for verification
117 ls -la
118
119 - name: Get tag name
120 id: tag
121 run: |
122 if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
123 echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
124 else
125 echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
126 fi
127
128 - name: Create Release
129 uses: softprops/action-gh-release@v1
130 with:
131 tag_name: ${{ steps.tag.outputs.tag }}
132 name: Grain CLI ${{ steps.tag.outputs.tag }}
133 draft: false
134 prerelease: false
135 files: |
136 release-assets/*
137 body: |
138 ## Grain CLI ${{ steps.tag.outputs.tag }}
139
140 ### Installation
141
142 Quick install:
143 ```bash
144 curl -L https://github.com/grainsocial/grain/releases/download/${{ steps.tag.outputs.tag }}/install.sh | bash
145 ```
146
147 Or download manually:
148
149 - **Linux x86_64**: `grain-linux-x86_64`
150 - **Linux aarch64**: `grain-linux-aarch64`
151 - **macOS Intel**: `grain-darwin-x86_64`
152 - **macOS Apple Silicon**: `grain-darwin-aarch64`
153 - **Windows x86_64**: `grain-windows-x86_64.exe`
154
155 ### Usage
156
157 ```bash
158 grain login
159 grain gallery list
160 grain gallery create
161 ```
162
163 ### Checksums
164
165 See `checksums.txt` for SHA256 checksums.
166 env:
167 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
168
169 test-install:
170 name: Test Installation
171 needs: build
172 strategy:
173 matrix:
174 os: [ubuntu-latest, macos-latest]
175 runs-on: ${{ matrix.os }}
176 steps:
177 - name: Checkout
178 uses: actions/checkout@v4
179
180 - name: Get tag name
181 id: tag
182 run: |
183 if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
184 echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
185 else
186 echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
187 fi
188
189 - name: Test install script
190 run: |
191 # Wait for release to be available
192 sleep 30
193
194 # Test the install script
195 curl -L https://github.com/grainsocial/grain/releases/download/${{ steps.tag.outputs.tag }}/install.sh | bash