mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
* fix: set persist-credentials explicitly for checkout https://woodruffw.github.io/zizmor/audits/#artipacked * fix: minimize permissions scope for workflows https://woodruffw.github.io/zizmor/audits/#excessive-permissions * fix: remove potential template injections https://woodruffw.github.io/zizmor/audits/#template-injection * fix: only pass needed secrets in workflow_call https://woodruffw.github.io/zizmor/audits/#secrets-inherit * fix: push perm for single-arch build jobs I hadn't realised these push to the registry too :x * chore: fix formatting * fix: $ * fix: retag job quoting * feat: static analysis job for gha workflows * chore: fix formatting * fix: clear last zizmor checks * fix: broken merge --------- Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
217 lines
8.7 KiB
YAML
217 lines
8.7 KiB
YAML
name: Docs deploy
|
|
on:
|
|
workflow_run: # zizmor: ignore[dangerous-triggers] no attacker inputs are used here
|
|
workflows: ['Docs build']
|
|
types:
|
|
- completed
|
|
|
|
jobs:
|
|
checks:
|
|
name: Docs Deploy Checks
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
actions: read
|
|
pull-requests: read
|
|
outputs:
|
|
parameters: ${{ steps.parameters.outputs.result }}
|
|
artifact: ${{ steps.get-artifact.outputs.result }}
|
|
steps:
|
|
- if: ${{ github.event.workflow_run.conclusion != 'success' }}
|
|
run: echo 'The triggering workflow did not succeed' && exit 1
|
|
- name: Get artifact
|
|
id: get-artifact
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
|
with:
|
|
script: |
|
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
run_id: context.payload.workflow_run.id,
|
|
});
|
|
let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
|
|
return artifact.name == "docs-build-output"
|
|
})[0];
|
|
if (!matchArtifact) {
|
|
console.log("No artifact found with the name docs-build-output, build job was skipped")
|
|
return { found: false };
|
|
}
|
|
return { found: true, id: matchArtifact.id };
|
|
- name: Determine deploy parameters
|
|
id: parameters
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
|
env:
|
|
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
|
with:
|
|
script: |
|
|
const eventType = context.payload.workflow_run.event;
|
|
const isFork = context.payload.workflow_run.repository.fork;
|
|
|
|
let parameters;
|
|
|
|
console.log({eventType, isFork});
|
|
|
|
if (eventType == "push") {
|
|
const branch = context.payload.workflow_run.head_branch;
|
|
console.log({branch});
|
|
const shouldDeploy = !isFork && branch == "main";
|
|
parameters = {
|
|
event: "branch",
|
|
name: "main",
|
|
shouldDeploy
|
|
};
|
|
} else if (eventType == "pull_request") {
|
|
let pull_number = context.payload.workflow_run.pull_requests[0]?.number;
|
|
if(!pull_number) {
|
|
const {HEAD_SHA} = process.env;
|
|
const response = await github.rest.search.issuesAndPullRequests({q: `repo:${{ github.repository }} is:pr sha:${HEAD_SHA}`,per_page: 1,})
|
|
const items = response.data.items
|
|
if (items.length < 1) {
|
|
throw new Error("No pull request found for the commit")
|
|
}
|
|
const pullRequestNumber = items[0].number
|
|
console.info("Pull request number is", pullRequestNumber)
|
|
pull_number = pullRequestNumber
|
|
}
|
|
const {data: pr} = await github.rest.pulls.get({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number
|
|
});
|
|
|
|
console.log({pull_number});
|
|
|
|
parameters = {
|
|
event: "pr",
|
|
name: `pr-${pull_number}`,
|
|
pr_number: pull_number,
|
|
shouldDeploy: true
|
|
};
|
|
} else if (eventType == "release") {
|
|
parameters = {
|
|
event: "release",
|
|
name: context.payload.workflow_run.head_branch,
|
|
shouldDeploy: !isFork
|
|
};
|
|
}
|
|
|
|
console.log(parameters);
|
|
return parameters;
|
|
|
|
deploy:
|
|
name: Docs Deploy
|
|
runs-on: ubuntu-latest
|
|
needs: checks
|
|
permissions:
|
|
contents: read
|
|
actions: read
|
|
pull-requests: write
|
|
if: ${{ fromJson(needs.checks.outputs.artifact).found && fromJson(needs.checks.outputs.parameters).shouldDeploy }}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Load parameters
|
|
id: parameters
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
|
env:
|
|
PARAM_JSON: ${{ needs.checks.outputs.parameters }}
|
|
with:
|
|
script: |
|
|
const parameters = JSON.parse(process.env.PARAM_JSON);
|
|
core.setOutput("event", parameters.event);
|
|
core.setOutput("name", parameters.name);
|
|
core.setOutput("shouldDeploy", parameters.shouldDeploy);
|
|
|
|
- name: Download artifact
|
|
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
|
env:
|
|
ARTIFACT_JSON: ${{ needs.checks.outputs.artifact }}
|
|
with:
|
|
script: |
|
|
let artifact = JSON.parse(process.env.ARTIFACT_JSON);
|
|
let download = await github.rest.actions.downloadArtifact({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
artifact_id: artifact.id,
|
|
archive_format: 'zip',
|
|
});
|
|
let fs = require('fs');
|
|
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/docs-build-output.zip`, Buffer.from(download.data));
|
|
|
|
- name: Unzip artifact
|
|
run: unzip "${{ github.workspace }}/docs-build-output.zip" -d "${{ github.workspace }}/docs/build"
|
|
|
|
- name: Deploy Docs Subdomain
|
|
env:
|
|
TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
|
|
TF_VAR_prefix_event_type: ${{ steps.parameters.outputs.event }}
|
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
|
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
|
with:
|
|
tg_version: '0.58.12'
|
|
tofu_version: '1.7.1'
|
|
tg_dir: 'deployment/modules/cloudflare/docs'
|
|
tg_command: 'apply'
|
|
|
|
- name: Deploy Docs Subdomain Output
|
|
id: docs-output
|
|
env:
|
|
TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
|
|
TF_VAR_prefix_event_type: ${{ steps.parameters.outputs.event }}
|
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
|
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
|
with:
|
|
tg_version: '0.58.12'
|
|
tofu_version: '1.7.1'
|
|
tg_dir: 'deployment/modules/cloudflare/docs'
|
|
tg_command: 'output -json'
|
|
|
|
- name: Output Cleaning
|
|
id: clean
|
|
env:
|
|
TG_OUTPUT: ${{ steps.docs-output.outputs.tg_action_output }}
|
|
run: |
|
|
CLEANED=$(echo "$TG_OUTPUT" | sed 's|%0A|\n|g ; s|%3C|<|g' | jq -c .)
|
|
echo "output=$CLEANED" >> $GITHUB_OUTPUT
|
|
|
|
- name: Publish to Cloudflare Pages
|
|
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
|
with:
|
|
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN_PAGES_UPLOAD }}
|
|
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
projectName: ${{ fromJson(steps.clean.outputs.output).pages_project_name.value }}
|
|
workingDirectory: 'docs'
|
|
directory: 'build'
|
|
branch: ${{ steps.parameters.outputs.name }}
|
|
wranglerVersion: '3'
|
|
|
|
- name: Deploy Docs Release Domain
|
|
if: ${{ steps.parameters.outputs.event == 'release' }}
|
|
env:
|
|
TF_VAR_prefix_name: ${{ steps.parameters.outputs.name}}
|
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
TF_STATE_POSTGRES_CONN_STR: ${{ secrets.TF_STATE_POSTGRES_CONN_STR }}
|
|
uses: gruntwork-io/terragrunt-action@9559e51d05873b0ea467c42bbabcb5c067642ccc # v2
|
|
with:
|
|
tg_version: '0.58.12'
|
|
tofu_version: '1.7.1'
|
|
tg_dir: 'deployment/modules/cloudflare/docs-release'
|
|
tg_command: 'apply'
|
|
|
|
- name: Comment
|
|
uses: actions-cool/maintain-one-comment@4b2dbf086015f892dcb5e8c1106f5fccd6c1476b # v3
|
|
if: ${{ steps.parameters.outputs.event == 'pr' }}
|
|
with:
|
|
number: ${{ fromJson(needs.checks.outputs.parameters).pr_number }}
|
|
body: |
|
|
📖 Documentation deployed to [${{ fromJson(steps.clean.outputs.output).immich_app_branch_subdomain.value }}](https://${{ fromJson(steps.clean.outputs.output).immich_app_branch_subdomain.value }})
|
|
emojis: 'rocket'
|
|
body-include: '<!-- Docs PR URL -->'
|