|
1 | 1 | name: Publish GitHub Action Repository |
2 | 2 |
|
3 | 3 | on: |
4 | | - release: |
5 | | - types: [published, edited] |
6 | 4 | workflow_dispatch: |
7 | | - inputs: |
8 | | - release_tag: |
9 | | - description: "Release tag to publish from the source repository" |
10 | | - required: false |
11 | | - default: "" |
12 | | - action_repository: |
13 | | - description: "Dedicated public repository that hosts the Marketplace action" |
14 | | - required: false |
15 | | - default: "hashgraph-online/hol-codex-plugin-scanner-action" |
16 | | - create_repository: |
17 | | - description: "Create the dedicated action repository if it does not exist" |
18 | | - required: false |
19 | | - default: true |
20 | | - type: boolean |
| 5 | + push: |
| 6 | + branches: |
| 7 | + - main |
| 8 | + paths: |
| 9 | + - action/action.yml |
| 10 | + - action/README.md |
| 11 | + - LICENSE |
| 12 | + - SECURITY.md |
| 13 | + - CONTRIBUTING.md |
21 | 14 |
|
22 | 15 | permissions: |
23 | 16 | contents: read |
24 | 17 |
|
25 | 18 | concurrency: |
26 | | - group: codex-plugin-scanner-action-publish-${{ github.event.release.tag_name || inputs.release_tag || github.ref }} |
| 19 | + group: codex-plugin-scanner-action-repo-${{ github.ref }} |
27 | 20 | cancel-in-progress: false |
28 | 21 |
|
29 | 22 | jobs: |
30 | 23 | publish-action-repo: |
31 | | - name: Publish GitHub Action Repository |
| 24 | + name: Sync action repo + publish release notes |
32 | 25 | runs-on: ubuntu-latest |
| 26 | + permissions: |
| 27 | + contents: read |
33 | 28 | env: |
34 | | - GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }} |
35 | | - ACTION_REPOSITORY: ${{ inputs.action_repository != '' && inputs.action_repository || vars.ACTION_REPOSITORY != '' && vars.ACTION_REPOSITORY || 'hashgraph-online/hol-codex-plugin-scanner-action' }} |
36 | | - RELEASE_TAG: ${{ github.event.release.tag_name || inputs.release_tag }} |
37 | | - CREATE_REPOSITORY: ${{ github.event_name == 'workflow_dispatch' && (inputs.create_repository && 'true' || 'false') || 'true' }} |
38 | | - PUBLISH_IMMUTABLE_RELEASE: ${{ github.event_name == 'release' || inputs.release_tag != '' }} |
39 | | - SOURCE_REF: ${{ github.event.release.tag_name || inputs.release_tag || github.ref_name }} |
| 29 | + ACTION_REPOSITORY: ${{ vars.ACTION_REPOSITORY != '' && vars.ACTION_REPOSITORY || 'hashgraph-online/hol-codex-plugin-scanner-action' }} |
| 30 | + SOURCE_REF: ${{ github.sha }} |
40 | 31 | SOURCE_REPOSITORY: ${{ github.repository }} |
41 | 32 | SOURCE_SERVER_URL: ${{ github.server_url }} |
42 | 33 | steps: |
43 | | - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
44 | | - with: |
45 | | - ref: ${{ github.event.release.tag_name || inputs.release_tag || github.ref }} |
46 | | - fetch-depth: 0 |
47 | | - |
48 | 34 | - name: Validate publication credentials |
| 35 | + env: |
| 36 | + ACTION_REPO_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }} |
49 | 37 | run: | |
50 | | - if [ -z "${GH_TOKEN}" ]; then |
51 | | - echo "ACTION_REPO_TOKEN is required to publish the GitHub Action repository." >&2 |
| 38 | + if [ -z "$ACTION_REPO_TOKEN" ]; then |
| 39 | + echo "ACTION_REPO_TOKEN must be configured to publish the Marketplace action repository." >&2 |
52 | 40 | exit 1 |
53 | 41 | fi |
54 | 42 |
|
55 | | - - name: Resolve version |
56 | | - id: version |
57 | | - run: | |
58 | | - TAG="${RELEASE_TAG}" |
59 | | - if [ -z "${TAG}" ]; then |
60 | | - TAG=$(python3 -c "import tomllib; p=tomllib.load(open('pyproject.toml','rb')); print('v' + p['project']['version'])") |
61 | | - fi |
62 | | - VERSION="${TAG#v}" |
63 | | - echo "tag=${TAG}" >> "${GITHUB_OUTPUT}" |
64 | | - echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" |
| 43 | + - name: Checkout source repository |
| 44 | + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd |
65 | 45 |
|
66 | | - - name: Ensure action repository exists |
67 | | - run: | |
68 | | - if gh repo view "${ACTION_REPOSITORY}" >/dev/null 2>&1; then |
69 | | - exit 0 |
70 | | - fi |
71 | | - if [ "${CREATE_REPOSITORY}" != "true" ]; then |
72 | | - echo "Action repository ${ACTION_REPOSITORY} does not exist and automatic creation is disabled." >&2 |
73 | | - exit 1 |
74 | | - fi |
75 | | - gh repo create "${ACTION_REPOSITORY}" \ |
76 | | - --public \ |
77 | | - --description "HOL Codex Plugin Scanner GitHub Action" \ |
78 | | - --homepage "${SOURCE_SERVER_URL}/${SOURCE_REPOSITORY}" \ |
79 | | - --disable-wiki |
80 | | -
|
81 | | - - name: Sync action repository contents |
| 46 | + - name: Compute next action release tag |
| 47 | + id: version |
| 48 | + env: |
| 49 | + GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }} |
82 | 50 | run: | |
83 | | - VERSION="${{ steps.version.outputs.version }}" |
84 | | - TAG="${{ steps.version.outputs.tag }}" |
85 | | - WORKDIR="${RUNNER_TEMP}/action-repository" |
86 | | - git clone "https://x-access-token:${GH_TOKEN}@github.com/${ACTION_REPOSITORY}.git" "${WORKDIR}" |
87 | | - cd "${WORKDIR}" |
| 51 | + LAST_TAG=$(gh release list --repo "$ACTION_REPOSITORY" --limit 1 --json tagName --jq '.[0].tagName // ""') |
88 | 52 |
|
89 | | - if git ls-remote --exit-code origin refs/heads/main >/dev/null 2>&1; then |
90 | | - git fetch origin main |
91 | | - git switch -C main origin/main |
| 53 | + if [ -z "$LAST_TAG" ]; then |
| 54 | + TAG="v1.0.0" |
92 | 55 | else |
93 | | - git switch --orphan main |
| 56 | + IFS=. read -r MAJOR MINOR PATCH <<< "${LAST_TAG#v}" |
| 57 | + if [ -z "$MAJOR" ] || [ -z "$MINOR" ] || [ -z "$PATCH" ]; then |
| 58 | + echo "Unsupported release tag format: $LAST_TAG" >&2 |
| 59 | + exit 1 |
| 60 | + fi |
| 61 | + TAG="v${MAJOR}.${MINOR}.$((PATCH + 1))" |
94 | 62 | fi |
95 | 63 |
|
96 | | - find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} + |
| 64 | + echo "tag=$TAG" >> "$GITHUB_OUTPUT" |
| 65 | +
|
| 66 | + - name: Clone action repository |
| 67 | + env: |
| 68 | + GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }} |
| 69 | + run: gh repo clone "$ACTION_REPOSITORY" action-repo -- --depth 1 |
97 | 70 |
|
| 71 | + - name: Sync root-ready action bundle |
| 72 | + working-directory: action-repo |
| 73 | + run: | |
98 | 74 | cp "${GITHUB_WORKSPACE}/action/action.yml" action.yml |
99 | 75 | cp "${GITHUB_WORKSPACE}/action/README.md" README.md |
100 | 76 | cp "${GITHUB_WORKSPACE}/LICENSE" LICENSE |
101 | 77 | cp "${GITHUB_WORKSPACE}/SECURITY.md" SECURITY.md |
| 78 | + cp "${GITHUB_WORKSPACE}/CONTRIBUTING.md" CONTRIBUTING.md |
102 | 79 |
|
103 | | - git config user.name "github-actions[bot]" |
104 | | - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" |
105 | | - git add action.yml README.md LICENSE SECURITY.md |
106 | | -
|
107 | | - HAS_HEAD=true |
108 | | - git rev-parse --verify HEAD >/dev/null 2>&1 || HAS_HEAD=false |
109 | | -
|
110 | | - if [ "${HAS_HEAD}" = "true" ] && git diff --cached --quiet; then |
111 | | - echo "No action repository content changes detected." |
| 80 | + - name: Detect sync changes |
| 81 | + id: diff |
| 82 | + working-directory: action-repo |
| 83 | + run: | |
| 84 | + if [ -n "$(git status --short -- action.yml README.md LICENSE SECURITY.md CONTRIBUTING.md)" ]; then |
| 85 | + echo "changed=true" >> "$GITHUB_OUTPUT" |
112 | 86 | else |
113 | | - git commit -m "chore: publish action bundle ${TAG}" |
114 | | - git push origin HEAD:main |
| 87 | + echo "changed=false" >> "$GITHUB_OUTPUT" |
115 | 88 | fi |
116 | 89 |
|
117 | | - git tag -f v1 |
118 | | - git push origin refs/tags/v1 --force |
| 90 | + - name: Commit synced bundle |
| 91 | + if: steps.diff.outputs.changed == 'true' |
| 92 | + working-directory: action-repo |
| 93 | + run: | |
| 94 | + git config user.name "github-actions[bot]" |
| 95 | + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" |
| 96 | + git add action.yml README.md LICENSE SECURITY.md CONTRIBUTING.md |
| 97 | + git commit -m "chore: publish action bundle ${{ steps.version.outputs.tag }}" |
119 | 98 |
|
120 | | - if [ "${PUBLISH_IMMUTABLE_RELEASE}" = "true" ]; then |
121 | | - git tag -f "${TAG}" |
122 | | - git push origin "refs/tags/${TAG}" --force |
123 | | - fi |
| 99 | + - name: Push action repository branch and tags |
| 100 | + if: steps.diff.outputs.changed == 'true' |
| 101 | + working-directory: action-repo |
| 102 | + run: | |
| 103 | + TAG="${{ steps.version.outputs.tag }}" |
| 104 | + git push origin HEAD:main |
| 105 | + git tag "$TAG" |
| 106 | + git push origin "refs/tags/${TAG}" |
| 107 | + git tag -fa v1 -m "Update floating major tag to ${TAG}" |
| 108 | + git push origin refs/tags/v1 --force |
124 | 109 |
|
125 | | - - name: Create or update action repository release |
126 | | - if: env.PUBLISH_IMMUTABLE_RELEASE == 'true' |
| 110 | + - name: Check action release state |
| 111 | + id: release_state |
| 112 | + working-directory: action-repo |
| 113 | + env: |
| 114 | + GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }} |
127 | 115 | run: | |
128 | | - VERSION="${{ steps.version.outputs.version }}" |
129 | 116 | TAG="${{ steps.version.outputs.tag }}" |
130 | | - if [ -n "${RELEASE_TAG}" ]; then |
131 | | - NOTES="Published automatically from ${SOURCE_SERVER_URL}/${SOURCE_REPOSITORY}/releases/tag/${TAG}" |
| 117 | +
|
| 118 | + if gh release view "${TAG}" --repo "$ACTION_REPOSITORY" >/dev/null 2>&1; then |
| 119 | + echo "release_exists=true" >> "$GITHUB_OUTPUT" |
132 | 120 | else |
133 | | - NOTES="Published automatically from ${SOURCE_SERVER_URL}/${SOURCE_REPOSITORY}/tree/${SOURCE_REF}" |
| 121 | + echo "release_exists=false" >> "$GITHUB_OUTPUT" |
134 | 122 | fi |
135 | 123 |
|
136 | | - if gh release view "${TAG}" --repo "${ACTION_REPOSITORY}" >/dev/null 2>&1; then |
137 | | - gh release edit "${TAG}" \ |
138 | | - --repo "${ACTION_REPOSITORY}" \ |
139 | | - --title "${TAG}" \ |
140 | | - --notes "${NOTES}" |
| 124 | + if git ls-remote --tags origin "refs/tags/${TAG}" | grep -q .; then |
| 125 | + echo "tag_exists=true" >> "$GITHUB_OUTPUT" |
141 | 126 | else |
142 | | - gh release create "${TAG}" \ |
143 | | - --repo "${ACTION_REPOSITORY}" \ |
144 | | - --title "${TAG}" \ |
145 | | - --notes "${NOTES}" |
| 127 | + echo "tag_exists=false" >> "$GITHUB_OUTPUT" |
146 | 128 | fi |
| 129 | +
|
| 130 | + - name: Create action repository release |
| 131 | + if: steps.release_state.outputs.release_exists == 'false' && (steps.diff.outputs.changed == 'true' || steps.release_state.outputs.tag_exists == 'true') |
| 132 | + env: |
| 133 | + GH_TOKEN: ${{ secrets.ACTION_REPO_TOKEN }} |
| 134 | + run: | |
| 135 | + TAG="${{ steps.version.outputs.tag }}" |
| 136 | + gh release create "${TAG}" \ |
| 137 | + --repo "$ACTION_REPOSITORY" \ |
| 138 | + --title "$TAG" \ |
| 139 | + --generate-notes \ |
| 140 | + --notes "Published automatically from ${SOURCE_SERVER_URL}/${SOURCE_REPOSITORY}/tree/${SOURCE_REF}" |
0 commit comments