Skip to content

Chore/upgrade next version #18

Chore/upgrade next version

Chore/upgrade next version #18

name: "PR Deployment"
on:
workflow_dispatch:
inputs:
pr_number:
description: "Pull Request Number"
required: true
type: number
tag_name:
description: "Tag/Version (z. B. v1.2.3-rc1)"
required: true
type: string
release_name:
description: "Release-Name"
required: false
default: ""
type: string
issue_comment:
types:
- "created"
pull_request_review_comment:
types:
- "created"
permissions: {}
jobs:
deploy:
name: "Create pre-release from PR"
if: >
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/deploy')
) ||
(
github.event_name == 'pull_request_review_comment' &&
startsWith(github.event.comment.body, '/deploy')
)
runs-on: "ubuntu-latest"
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: "Resolve deployment inputs"
id: "resolve"
shell: "bash"
env:
EVENT_NAME: "${{ github.event_name }}"
INPUT_PR_NUMBER: "${{ inputs.pr_number }}"
INPUT_TAG_NAME: "${{ inputs.tag_name }}"
INPUT_RELEASE_NAME: "${{ inputs.release_name }}"
COMMENT_BODY: "${{ github.event.comment.body }}"
COMMENT_PR_NUMBER: "${{ github.event.issue.number }}"
REVIEW_COMMENT_PR_NUMBER: "${{ github.event.pull_request.number }}"
run: |
if [[ "${EVENT_NAME}" == "workflow_dispatch" ]]; then
pr_number="${INPUT_PR_NUMBER}"
tag_name="${INPUT_TAG_NAME}"
release_name="${INPUT_RELEASE_NAME}"
elif [[ "${EVENT_NAME}" == "pull_request_review_comment" ]]; then
# Command format: /deploy [release name]
tag_name=""
release_name="${COMMENT_BODY#/deploy}"
release_name="${release_name# }"
pr_number="${REVIEW_COMMENT_PR_NUMBER}"
else
# Command format: /deploy [release name]
tag_name=""
release_name="${COMMENT_BODY#/deploy}"
release_name="${release_name# }"
pr_number="${COMMENT_PR_NUMBER}"
fi
echo "pr_number=${pr_number}" >> "$GITHUB_OUTPUT"
echo "tag_name=${tag_name}" >> "$GITHUB_OUTPUT"
echo "release_name=${release_name}" >> "$GITHUB_OUTPUT"
# Authorization policy:
# - Users who invoke this workflow (manual dispatch or /deploy comments) must have
# at least write-level repository permission.
# - Allowed levels are: write, maintain, admin.
# - We prefer github.triggering_actor when available so workflow re-runs are checked
# against the user who clicked re-run instead of the original actor.
# This gate blocks all downstream checkout/tag/release steps when unauthorized.
- name: "Authorize deployment actor"
id: "authorize"
uses: "actions/github-script@v7"
env:
REQUESTED_BY: "${{ github.triggering_actor != '' && github.triggering_actor || github.actor }}"
with:
script: |
const allowedPermissions = new Set(['write', 'maintain', 'admin']);
const requestedBy = process.env.REQUESTED_BY;
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: requestedBy,
});
const permission = data.permission;
core.info(`Deployment requested by '${requestedBy}' with '${permission}' permission.`);
if (!allowedPermissions.has(permission)) {
core.setFailed(
`Deployment denied for @${requestedBy}: repository permission '${permission}' is below required level. ` +
`Allowed permissions: ${Array.from(allowedPermissions).join(', ')}.`
);
return;
}
core.info(`Authorization gate passed for @${requestedBy}.`);
- name: "Checkout PR merge commit"
uses: "actions/checkout@v4.1.0"
with:
ref: "refs/pull/${{ steps.resolve.outputs.pr_number }}/merge"
fetch-depth: 0
- name: "Determine effective tag"
id: "effective"
shell: "bash"
env:
RESOLVED_TAG: "${{ steps.resolve.outputs.tag_name }}"
PR_NUMBER: "${{ steps.resolve.outputs.pr_number }}"
RUN_ID: "${{ github.run_id }}"
run: |
if [[ -n "${RESOLVED_TAG}" ]]; then
tag_name="${RESOLVED_TAG}"
else
version="$(python -c 'import json; print(json.load(open("custom_components/samsung_soundbar/manifest.json"))["version"])')"
tag_name="v${version}-pr${PR_NUMBER}-run${RUN_ID}"
fi
echo "tag_name=${tag_name}" >> "$GITHUB_OUTPUT"
- name: "Validate tag format"
shell: "bash"
run: |
if [[ ! "${{ steps.effective.outputs.tag_name }}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
echo "Tag '${{ steps.effective.outputs.tag_name }}' does not look like a semantic version." >&2
exit 1
fi
- name: "Create pre-release"
uses: "softprops/action-gh-release@v2"
with:
tag_name: "${{ steps.effective.outputs.tag_name }}"
target_commitish: "${{ github.sha }}"
prerelease: true
generate_release_notes: true
name: "${{ steps.resolve.outputs.release_name != '' && steps.resolve.outputs.release_name || steps.effective.outputs.tag_name }}"
body: |
Automated pre-release from PR #${{ steps.resolve.outputs.pr_number }}.
- name: "Package integration"
shell: "bash"
run: |
cd "${{ github.workspace }}/custom_components/samsung_soundbar"
zip -r samsung_soundbar.zip ./
- name: "Attach integration package to pre-release"
uses: "softprops/action-gh-release@v2"
with:
tag_name: "${{ steps.effective.outputs.tag_name }}"
files: "${{ github.workspace }}/custom_components/samsung_soundbar/samsung_soundbar.zip"
- name: "Comment on PR with release link"
uses: "actions/github-script@v7"
env:
RELEASE_URL: "https://github.com/${{ github.repository }}/releases/tag/${{ steps.effective.outputs.tag_name }}"
with:
script: |
const prNumber = Number('${{ steps.resolve.outputs.pr_number }}');
const releaseUrl = process.env.RELEASE_URL;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `🚀 Pre-release erstellt: ${releaseUrl}`,
});