LabCodeHub öffentliche Ansicht
Anmelden
Küpper / Quildrop öffentlich

fix: add binary release

R Rüdiger Küpper <rpr@9it.de> committete am 19.02.2026 06:34
7b66c42f46108d01c89382b771faf6c838759cce
2 geänderte Datei(en) +334 −1
Kontextzeilen: 0 1 2 3 10
hinzugefügt .github/workflows/release-quilldrop.yml
+333 −0 Datei ansehen
@@ -0,0 +1,333 @@
1 +
name: build-and-release
2 +
3 +
on:
4 +
  # push:
5 +
  #   branches: [main]
6 +
  workflow_dispatch:
7 +
    # tags:
8 +
    #   - 'v*' # z.B. v1.2.3
9 +
10 +
permissions:
11 +
  contents: read
12 +
  packages: write
13 +
  id-token: write
14 +
15 +
env:
16 +
  # Hier kannst du einen Default-Name definieren, der in die Artefakte wandert
17 +
  APP_VERSION: ${{ github.ref_name }}
18 +
  GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
19 +
  TARGET_REPO: owner/target-repo
20 +
  TAG: ${{ github.ref_name }}
21 +
  REGISTRY: ghcr.io
22 +
  IMAGE_NAME: ${{ github.repository }}-2
23 +
24 +
jobs:
25 +
26 +
  # Job 1: Automatisches Semver Tagging
27 +
  # create-version-tag:
28 +
  #   name: Create Version Tag
29 +
  #   # runs-on: ubuntu-latest
30 +
  #   # runs-on: [self-hosted, macbook]
31 +
  #   runs-on: [self-hosted]
32 +
  #   outputs:
33 +
  #     new_tag: ${{ steps.tag_version.outputs.new_tag }}
34 +
  #     changelog: ${{ steps.tag_version.outputs.changelog }}
35 +
  #   permissions:
36 +
  #     contents: write
37 +
  #   steps:
38 +
  #     - name: Checkout
39 +
  #       uses: actions/checkout@v6
40 +
  #       with:
41 +
  #         fetch-depth: 0
42 +
43 +
  #     - name: Bump version and push tag
44 +
  #       id: tag_version
45 +
  #       uses: mathieudutour/github-tag-action@v6.2
46 +
  #       with:
47 +
  #         github_token: ${{ secrets.GITHUB_TOKEN }}
48 +
  #         default_bump: patch
49 +
  #         release_branches: main
50 +
  #         # fix: = patch (0.0.1)
51 +
  #         # feat: = minor (0.1.0)
52 +
  #         # BREAKING CHANGE: = major (1.0.0)
53 +
54 +
  #     - name: Show new version
55 +
  #       run: |
56 +
  #         echo "New version: ${{ steps.tag_version.outputs.new_tag }}"
57 +
  #         echo "Changelog: ${{ steps.tag_version.outputs.changelog }}"
58 +
59 +
  create-version-tag:
60 +
    uses: 9it-full-service/shared-workflows/.github/workflows/prepare.yml@main
61 +
    with:
62 +
      version_override: ${{ github.event.inputs.version || '' }}
63 +
      default_version: 'dev'
64 +
65 +
  build:
66 +
    runs-on: [ arc-runner-set-arm64 ]
67 +
    # runs-on: [ self-hosted ]
68 +
    needs: [ "create-version-tag" ]
69 +
    strategy:
70 +
      fail-fast: false
71 +
      matrix:
72 +
        # goos: [linux,]
73 +
        # goarch: [arm64]
74 +
        goos: [linux, darwin]
75 +
        goarch: [amd64, arm64]
76 +
        # goos: [linux, darwin, windows]
77 +
        # goarch: [amd64, arm64,arm]
78 +
        # exclude:
79 +
        #   # ARM 32-bit ist nur für Linux sinnvoll
80 +
        #   - goos: darwin
81 +
        #     goarch: arm
82 +
        #   - goos: windows
83 +
        #     goarch: arm
84 +
85 +
    steps:
86 +
      - uses: actions/checkout@v6
87 +
88 +
      - name: Setup Go
89 +
        uses: actions/setup-go@v6
90 +
        with:
91 +
          go-version: '1.25'
92 +
          cache: true
93 +
94 +
      # - name: Print build matrix
95 +
      #   run: |
96 +
      #     echo "GOOS=${{ matrix.goos }}"
97 +
      #     echo "GOARCH=${{ matrix.goarch }}"
98 +
      #     echo "TAG=${{ github.ref_name }}"
99 +
100 +
      - name: Set build timestamp
101 +
        id: timestamp
102 +
        run: echo "BUILD_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_OUTPUT
103 +
104 +
      - name: Print build matrix
105 +
        run: |
106 +
          echo "GOOS=${{ matrix.goos }}"
107 +
          echo "GOARCH=${{ matrix.goarch }}"
108 +
          echo "TAG=${{ needs.create-version-tag.outputs.version }}"
109 +
          echo "VERSION=${{ needs.create-version-tag.outputs.version }}"
110 +
          echo "COMMIT=${{ github.sha }}"
111 +
          echo "BUILD_TIMESTAMP=${{ steps.timestamp.outputs.BUILD_TIMESTAMP }}"
112 +
113 +
      - name: Build quilldrop
114 +
        env:
115 +
          GOOS: ${{ matrix.goos }}
116 +
          GOARCH: ${{ matrix.goarch }}
117 +
          VERSION: ${{ needs.create-version-tag.outputs.version }}
118 +
          COMMIT: ${{ github.sha }}
119 +
          BUILD_TIMESTAMP: ${{ steps.timestamp.outputs.BUILD_TIMESTAMP }}
120 +
        run: |
121 +
          set -euo pipefail
122 +
          mkdir -p dist
123 +
          BIN_NAME="quilldrop-${GOOS}-${GOARCH}"
124 +
          OUT="dist/${BIN_NAME}"
125 +
          # Windows: .exe
126 +
          if [ "${GOOS}" = "windows" ]; then OUT="${OUT}.exe"; fi
127 +
          # Build (im Unterordner)
128 +
          (cd . && CGO_ENABLED=0 go build -trimpath -ldflags="-s -w \
129 +
          -X 'main.version=${VERSION}' \
130 +
          -X 'main.commit=${COMMIT}' \
131 +
          -X 'main.date=${BUILD_TIMESTAMP}'" -o "../${OUT}")
132 +
          # go mod init quilldrop && go mod tidy && \
133 +
          go mod tidy && \
134 +
          # CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
135 +
          # -ldflags="-s -w \
136 +
          #   -X 'main.version=${VERSION}' \
137 +
          #   -X 'main.commit=${COMMIT}' \
138 +
          #   -X 'main.date=${BUILD_TIMESTAMP}'" \
139 +
          # -o vm-tracker-api main.go
140 +
          # Paket
141 +
          if [[ "${OUT}" == *.exe ]]; then
142 +
            (cd dist && zip "${BIN_NAME}.zip" "${BIN_NAME}.exe")
143 +
          else
144 +
            (cd dist && tar -czf "${BIN_NAME}.tar.gz" "${BIN_NAME}")
145 +
          fi
146 +
147 +
      - name: Build vm-tracker-client
148 +
        env:
149 +
          GOOS: ${{ matrix.goos }}
150 +
          GOARCH: ${{ matrix.goarch }}
151 +
          VERSION: ${{ needs.create-version-tag.outputs.version }}  # ← hinzufügen
152 +
          COMMIT: ${{ github.sha }}                                  # ← hinzufügen
153 +
          # BUILD_TIMESTAMP: ${{ github.event.head_commit.timestamp }}
154 +
          BUILD_TIMESTAMP: $(date -u +%Y-%m-%dT%H:%M:%SZ)
155 +
        run: |
156 +
          set -euo pipefail
157 +
          mkdir -p dist
158 +
          BIN_NAME="quilldrop-${GOOS}-${GOARCH}"
159 +
          OUT="dist/${BIN_NAME}"
160 +
          if [ "${GOOS}" = "windows" ]; then OUT="${OUT}.exe"; fi
161 +
          (cd . && CGO_ENABLED=0 go build -trimpath -ldflags="-s -w \
162 +
          -X 'main.version=${VERSION}' \
163 +
          -X 'main.commit=${COMMIT}' \
164 +
          -X 'main.date=${BUILD_TIMESTAMP}'" -o "../${OUT}")
165 +
          if [[ "${OUT}" == *.exe ]]; then
166 +
            (cd dist && zip "${BIN_NAME}.zip" "${BIN_NAME}.exe")
167 +
          else
168 +
            (cd dist && tar -czf "${BIN_NAME}.tar.gz" "${BIN_NAME}")
169 +
          fi
170 +
171 +
      - name: Checksums erzeugen
172 +
        run: |
173 +
          set -euo pipefail
174 +
          cd dist
175 +
          # Ein Checksum-File pro Matrix-Kombination
176 +
          # FILE="CHECKSUMS-${{ env.APP_VERSION }}-${{ matrix.goos }}-${{ matrix.goarch }}.txt"
177 +
          FILE="CHECKSUMS-${{ needs.create-version-tag.outputs.version }}-${{ matrix.goos }}-${{ matrix.goarch }}.txt"
178 +
          shopt -s nullglob
179 +
          for f in *.tar.gz *.zip; do
180 +
            sha256sum "$f" >> "$FILE"
181 +
          done
182 +
          cat "$FILE"
183 +
184 +
      - name: Upload artifacts (unique per matrix)
185 +
        uses: actions/upload-artifact@v5
186 +
        with:
187 +
          name: release-bundles-${{ matrix.goos }}-${{ matrix.goarch }}-${{ github.run_attempt }}
188 +
          path: |
189 +
            dist/*.tar.gz
190 +
            dist/*.zip
191 +
            dist/CHECKSUMS-*.txt
192 +
          if-no-files-found: error
193 +
          compression-level: 6
194 +
195 +
  release:
196 +
    needs: [ "build", "create-version-tag" ]
197 +
    runs-on: ubuntu-latest
198 +
    steps:
199 +
      - name: Download all build artifacts (merged)
200 +
        uses: actions/download-artifact@v6
201 +
        with:
202 +
          pattern: release-bundles-*
203 +
          merge-multiple: true
204 +
          path: dist
205 +
206 +
      - name: Übersicht
207 +
        run: ls -la dist
208 +
209 +
      # --- Option A: Release in anderes Repo via gh CLI ---
210 +
      - name: Create release in target repo
211 +
        env:
212 +
          GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}   # 👈 wichtig: GH_TOKEN, nicht RELEASE_TOKEN
213 +
          TARGET_REPO: 9it-full-service/quilldrop
214 +
          TAG: ${{ needs.create-version-tag.outputs.version }}
215 +
          # TAG: ${{ github.ref_name }}
216 +
        run: |
217 +
          set -euo pipefail
218 +
          gh release create "$TAG" \
219 +
            --repo "$TARGET_REPO" \
220 +
            --title "$TAG" \
221 +
            --notes "Automated release from ${GITHUB_REPOSITORY}@${GITHUB_SHA}" \
222 +
          || echo "Release exists, continue to upload assets."
223 +
224 +
          gh release upload "$TAG" dist/* --repo "$TARGET_REPO" --clobber
225 +
226 +
  # build-and-push-docker:
227 +
  #   name: Build Multi-arch Docker
228 +
  #   needs: [create-version-tag, build]
229 +
  #   runs-on: [self-hosted]
230 +
  #   permissions:
231 +
  #     contents: read
232 +
  #     packages: write
233 +
  #   steps:
234 +
  #     - name: Checkout repository
235 +
  #       uses: actions/checkout@v6
236 +
237 +
  #     # Alle Artifacts herunterladen
238 +
  #     - name: Download build artifacts
239 +
  #       uses: actions/download-artifact@v6
240 +
  #       with:
241 +
  #         path: ./artifacts
242 +
243 +
  #     # Übersicht was heruntergeladen wurde
244 +
  #     - name: List downloaded artifacts
245 +
  #       run: |
246 +
  #         echo "=== Downloaded artifacts ==="
247 +
  #         ls -laR artifacts/
248 +
249 +
  #     # Binaries für Docker vorbereiten
250 +
  #     - name: Prepare binaries for Docker
251 +
  #       run: |
252 +
  #         set -euo pipefail
253 +
  #         mkdir -p docker-bin/{amd64,arm64}
254 +
          
255 +
  #         # Suche und extrahiere amd64 binary
256 +
  #         echo "Searching for amd64 binary..."
257 +
  #         AMD64_TAR=$(find artifacts -name "vm-tracker-api-linux-amd64.tar.gz" -type f | head -1)
258 +
  #         if [ -n "$AMD64_TAR" ]; then
259 +
  #           echo "Found: $AMD64_TAR"
260 +
  #           tar -xzf "$AMD64_TAR" -C docker-bin/amd64/
261 +
  #           mv docker-bin/amd64/vm-tracker-api-linux-amd64 docker-bin/amd64/vm-tracker-api
262 +
  #           chmod +x docker-bin/amd64/vm-tracker-api
263 +
  #         else
264 +
  #           echo "ERROR: amd64 binary not found!"
265 +
  #           exit 1
266 +
  #         fi
267 +
          
268 +
  #         # Suche und extrahiere arm64 binary
269 +
  #         echo "Searching for arm64 binary..."
270 +
  #         ARM64_TAR=$(find artifacts -name "vm-tracker-api-linux-arm64.tar.gz" -type f | head -1)
271 +
  #         if [ -n "$ARM64_TAR" ]; then
272 +
  #           echo "Found: $ARM64_TAR"
273 +
  #           tar -xzf "$ARM64_TAR" -C docker-bin/arm64/
274 +
  #           mv docker-bin/arm64/vm-tracker-api-linux-arm64 docker-bin/arm64/vm-tracker-api
275 +
  #           chmod +x docker-bin/arm64/vm-tracker-api
276 +
  #         else
277 +
  #           echo "ERROR: arm64 binary not found!"
278 +
  #           exit 1
279 +
  #         fi
280 +
          
281 +
  #         echo "=== Prepared binaries ==="
282 +
  #         ls -la docker-bin/*/
283 +
  #         file docker-bin/*/vm-tracker-api
284 +
285 +
  #     - name: Set up QEMU
286 +
  #       uses: docker/setup-qemu-action@v3
287 +
288 +
  #     - name: Set up Docker Buildx
289 +
  #       uses: docker/setup-buildx-action@v3
290 +
291 +
  #     - name: Log in to Container Registry
292 +
  #       uses: docker/login-action@v3
293 +
  #       with:
294 +
  #         registry: ${{ env.REGISTRY }}
295 +
  #         username: ${{ github.actor }}
296 +
  #         password: ${{ secrets.GITHUB_TOKEN }}
297 +
298 +
  #     - name: Set build metadata
299 +
  #       id: meta
300 +
  #       run: |
301 +
  #         echo "VERSION=${{ needs.create-version-tag.outputs.new_tag }}" >> $GITHUB_ENV
302 +
  #         echo "COMMIT=${GITHUB_SHA}" >> $GITHUB_ENV
303 +
  #         echo "BUILD_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> $GITHUB_ENV
304 +
305 +
  #     - name: Build and push Docker image
306 +
  #       uses: docker/build-push-action@v6
307 +
  #       with:
308 +
  #         context: .
309 +
  #         platforms: linux/amd64,linux/arm64
310 +
  #         push: true
311 +
  #         tags: |
312 +
  #           ghcr.io/9it-full-service/vm-tracker-api:${{ needs.create-version-tag.outputs.new_tag }}
313 +
  #           ghcr.io/9it-full-service/vm-tracker-api:latest
314 +
  #         labels: |
315 +
  #           org.opencontainers.image.version=${{ needs.create-version-tag.outputs.new_tag }}
316 +
  #           org.opencontainers.image.created=${{ env.BUILD_TIMESTAMP }}
317 +
  #           org.opencontainers.image.revision=${{ github.sha }}
318 +
  #         build-args: |
319 +
  #           VERSION=${{ env.VERSION }}
320 +
  #           COMMIT=${{ env.COMMIT }}
321 +
  #           BUILD_TIMESTAMP=${{ env.BUILD_TIMESTAMP }}
322 +
  #         # cache-from: type=gha
323 +
  #         # cache-to: type=gha,mode=max
324 +
  #         provenance: false
325 +
326 +
  #     # - name: Clean up Docker images
327 +
  #     #   if: always()  # Also run in case of errors
328 +
  #     #   run: |
329 +
  #     #     # remove dangling images
330 +
  #     #     docker rmi ghcr.io/9it-full-service/vm-tracker-api:${{ needs.create-version-tag.outputs.new_tag }}
331 +
  #     #     docker rmi ghcr.io/9it-full-service/vm-tracker-api:latest
332 +
  #     #     # docker image prune -f
333 +
geändert content/2026-06-19-quilldrop-mein-eigenes-blog-cms.md
+1 −1 Datei ansehen
@@ -95,15 +95,15 @@ Die gesamte Konfiguration läuft über eine einzige `config.yaml`. Keine verstec
95 95
## Dual-Mode: Entwicklung und Produktion
96 96
97 97
Für die lokale Entwicklung starte ich `quilldrop serve` und sehe sofort jede Änderung im Browser. Für das Deployment auf den Webserver läuft `quilldrop generate` und spuckt statische HTML-Dateien aus, die direkt auf Nginx, Apache oder einem CDN liegen können.
98 98
99 99
Das ist das Schöne an einem Static Site Generator: Die fertige Seite ist nur noch HTML, CSS und ein bisschen JavaScript. Kein PHP, kein Ruby, kein Node.js auf dem Server. Einfach Dateien ausliefern.
100 100
101 101
## Fazit
102 102
103 103
Nach Jahren mit verschiedenen CMS-Systemen läuft der Blog jetzt auf meiner eigenen Software. Alles ist migriert, alle Funktionen sind da und das System macht genau das, was es soll - nicht mehr und nicht weniger.
104 104
105 -
Der Code ist Open Source und auf [GitHub](https://github.com/ruedigerp/quilldrop) [^verfügbar]. Wer einen schnellen, minimalistischen Blog ohne Overhead sucht, kann sich QuillDrop gerne anschauen.
105 +
Der Code ist Open Source und auf [GitHub](https://github.com/9it-full-service/quilldrop) [^verfügbar]. Wer einen schnellen, minimalistischen Blog ohne Overhead sucht, kann sich QuillDrop gerne anschauen.
106 106
107 107
> Write. Save. Published.
108 108
109 109
[^verfügbar]: Noch nicht, das kommt die Tage noch. Es gibt ein Update, so bald das Repo öffentlich ist.
\ No newline at end of file