name: Manage release PR on: workflow_dispatch: push: branches: - main concurrency: group: ${{ github.workflow }} cancel-in-progress: true permissions: {} jobs: bump: runs-on: ubuntu-latest steps: - name: Generate a token id: generate-token uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Checkout uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: token: ${{ steps.generate-token.outputs.token }} persist-credentials: true ref: main - name: Install uv uses: astral-sh/setup-uv@5a7eac68fb9809dea845d802897dc5c723910fa3 # v7.1.3 - name: Setup pnpm uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 - name: Setup Node uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version-file: './server/.nvmrc' cache: 'pnpm' cache-dependency-path: '**/pnpm-lock.yaml' - name: Determine release type id: bump-type uses: ietf-tools/semver-action@c90370b2958652d71c06a3484129a4d423a6d8a8 # v1.11.0 with: token: ${{ steps.generate-token.outputs.token }} - name: Bump versions env: TYPE: ${{ steps.bump-type.outputs.bump }} run: | if [ "$TYPE" == "none" ]; then exit 1 # TODO: Is there a cleaner way to abort the workflow? fi misc/release/pump-version.sh -s $TYPE -m true - name: Manage Outline release document id: outline uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: OUTLINE_API_KEY: ${{ secrets.OUTLINE_API_KEY }} NEXT_VERSION: ${{ steps.bump-type.outputs.next }} with: github-token: ${{ steps.generate-token.outputs.token }} script: | const fs = require('fs'); const outlineKey = process.env.OUTLINE_API_KEY; const parentDocumentId = 'da856355-0844-43df-bd71-f8edce5382d9' const collectionId = 'e2910656-714c-4871-8721-447d9353bd73'; const baseUrl = 'https://outline.immich.cloud'; const listResponse = await fetch(`${baseUrl}/api/documents.list`, { method: 'POST', headers: { 'Authorization': `Bearer ${outlineKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ parentDocumentId }) }); if (!listResponse.ok) { throw new Error(`Outline list failed: ${listResponse.statusText}`); } const listData = await listResponse.json(); const allDocuments = listData.data || []; const document = allDocuments.find(doc => doc.title === 'next'); let documentId; let documentUrl; let documentText; if (!document) { // Create new document console.log('No existing document found. Creating new one...'); const notesTmpl = fs.readFileSync('misc/release/notes.tmpl', 'utf8'); const createResponse = await fetch(`${baseUrl}/api/documents.create`, { method: 'POST', headers: { 'Authorization': `Bearer ${outlineKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'next', text: notesTmpl, collectionId: collectionId, parentDocumentId: parentDocumentId, publish: true }) }); if (!createResponse.ok) { throw new Error(`Failed to create document: ${createResponse.statusText}`); } const createData = await createResponse.json(); documentId = createData.data.id; const urlId = createData.data.urlId; documentUrl = `${baseUrl}/doc/next-${urlId}`; documentText = createData.data.text || ''; console.log(`Created new document: ${documentUrl}`); } else { documentId = document.id; const docPath = document.url; documentUrl = `${baseUrl}${docPath}`; documentText = document.text || ''; console.log(`Found existing document: ${documentUrl}`); } // Generate GitHub release notes console.log('Generating GitHub release notes...'); const releaseNotesResponse = await github.rest.repos.generateReleaseNotes({ owner: context.repo.owner, repo: context.repo.repo, tag_name: `${process.env.NEXT_VERSION}`, }); // Combine the content const changelog = ` # ${process.env.NEXT_VERSION} ${documentText} ${releaseNotesResponse.data.body} --- ` const existingChangelog = fs.existsSync('CHANGELOG.md') ? fs.readFileSync('CHANGELOG.md', 'utf8') : ''; fs.writeFileSync('CHANGELOG.md', changelog + existingChangelog, 'utf8'); core.setOutput('document_url', documentUrl); - name: Create PR id: create-pr uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 with: token: ${{ steps.generate-token.outputs.token }} commit-message: 'chore: release ${{ steps.bump-type.outputs.next }}' title: 'chore: release ${{ steps.bump-type.outputs.next }}' body: 'Release notes: ${{ steps.outline.outputs.document_url }}' labels: 'changelog:skip' branch: 'release/next' draft: true