Skip to content

Commit e539242

Browse files
authored
Merge pull request #29 from uclahs-cds/nwiltsie-attach-tarball
Explicitly manage secrets, add capability to attach source tarball
2 parents a452e40 + cc40672 commit e539242

13 files changed

+162
-24
lines changed

.github/workflows/internal-alias.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,3 @@ permissions:
1616
jobs:
1717
update-alias:
1818
uses: ./.github/workflows/wf-alias-release.yaml
19-
# Secrets are only required until tool-create-release is made public
20-
secrets: inherit

.github/workflows/internal-finalize.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
finalize-release:
2020
if: ${{ github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'automation-create-release') }}
2121
uses: ./.github/workflows/wf-finalize-release.yaml
22-
secrets: inherit
2322
with:
2423
draft: false
24+
secrets:
25+
token: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}

.github/workflows/internal-prepare.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@ jobs:
2929
with:
3030
bump_type: ${{ inputs.bump_type }}
3131
prerelease: ${{ inputs.prerelease }}
32-
# Secrets are only required until tool-create-release is made public
33-
secrets: inherit
32+
secrets:
33+
token: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}

.github/workflows/wf-alias-release.yaml

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
---
22
on:
33
workflow_call:
4+
inputs:
5+
# These inputs are taken directly from stefanzweifel/git-auto-commit-action
6+
commit-user-name:
7+
type: string
8+
description: Name used for the commit user
9+
required: false
10+
default: github-actions[bot]
11+
commit-user-email:
12+
type: string
13+
description: Email address used for the commit user
14+
required: false
15+
default: 41898282+github-actions[bot]@users.noreply.github.com
16+
secrets:
17+
token:
18+
description: >
19+
Personal access token (PAT) used to fetch the repository. Required
20+
if the repository has any private submodules.
21+
required: false
422

523
jobs:
624
alias-release:
@@ -14,7 +32,7 @@ jobs:
1432
env:
1533
REPO: ${{ github.repository }}
1634
RUN_ID: ${{ github.run_id }}
17-
GH_TOKEN: ${{ github.token }}
35+
GH_TOKEN: ${{ secrets.token || github.token }}
1836
run: |
1937
ACTION_DATA=$(gh api "repos/$REPO/actions/runs/$RUN_ID")
2038
echo "::debug::$ACTION_DATA"
@@ -27,14 +45,14 @@ jobs:
2745
repository: uclahs-cds/tool-create-release
2846
path: reusable
2947
ref: ${{ steps.workflow-parsing.outputs.SHA }}
30-
token: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}
3148

3249
- name: Checkout calling repository
3350
uses: actions/checkout@v4
3451
with:
3552
path: caller
3653
fetch-depth: 0
3754
fetch-tags: true
55+
token: ${{ secrets.token || github.token }}
3856

3957
- name: Set up python
4058
uses: actions/setup-python@v5
@@ -47,9 +65,11 @@ jobs:
4765
# Update the alias if necessary
4866
- id: alias-release
4967
run: |
50-
git config --file "$REPO_DIR/.git/config" user.name "github-actions[bot]"
51-
git config --file "$REPO_DIR/.git/config" user.email "41898282+github-actions[bot]@users.noreply.github.com"
68+
git config --file "$REPO_DIR/.git/config" user.name "$COMMIT_USER"
69+
git config --file "$REPO_DIR/.git/config" user.email "$COMMIT_EMAIL"
5270
alias-release "$REPO_DIR" "$GITHUB_REF"
5371
env:
5472
REPO_DIR: caller
55-
GH_TOKEN: ${{ github.token }}
73+
GH_TOKEN: ${{ secrets.token || github.token }}
74+
COMMIT_USER: ${{ inputs.commit-user-name }}
75+
COMMIT_EMAIL: ${{ inputs.commit-user-email }}

.github/workflows/wf-finalize-release.yaml

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ on:
66
description: If true (the default), draft the release for later manual approval.
77
type: boolean
88
default: true
9+
attach-tarball:
10+
description: If true, attach a tarball including all submodules to the release.
11+
type: boolean
12+
default: false
13+
14+
secrets:
15+
token:
16+
description: >
17+
Personal access token (PAT) used to fetch the repository and submodules.
18+
Required if `draft` is false (to allow triggering alias workflow) or if
19+
`attach-tarball` is true _and_ one or more of the submodules are private.
20+
required: false
921

1022
jobs:
1123
finalize-release:
@@ -19,7 +31,7 @@ jobs:
1931
env:
2032
REPO: ${{ github.repository }}
2133
RUN_ID: ${{ github.run_id }}
22-
GH_TOKEN: ${{ github.token }}
34+
GH_TOKEN: ${{ secrets.token || github.token }}
2335
run: |
2436
ACTION_DATA=$(gh api "repos/$REPO/actions/runs/$RUN_ID")
2537
echo "::debug::$ACTION_DATA"
@@ -32,7 +44,6 @@ jobs:
3244
repository: uclahs-cds/tool-create-release
3345
path: reusable
3446
ref: ${{ steps.workflow-parsing.outputs.SHA }}
35-
token: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}
3647

3748
- name: Set up python
3849
uses: actions/setup-python@v5
@@ -42,9 +53,29 @@ jobs:
4253
# Install the bundled package
4354
- run: pip install ./reusable
4455

56+
- name: Establish variables for tarball attachment
57+
id: set-repo-name
58+
run: |
59+
REPO_NAME=$(echo "${{ github.repository }}" | cut -d'/' -f2)
60+
echo "REPO_NAME=$REPO_NAME" >> "$GITHUB_OUTPUT"
61+
mkdir source
62+
echo "CLONE_PATH=source/$REPO_NAME" >> "$GITHUB_OUTPUT"
63+
64+
# Only check out the calling repository if we're going to attach a
65+
# tarball to the release
66+
- name: Clone repository to create tarball
67+
uses: actions/checkout@v4
68+
if: ${{ inputs.attach-tarball }}
69+
with:
70+
path: ${{ steps.set-repo-name.outputs.CLONE_PATH }}
71+
submodules: 'recursive'
72+
token: ${{ secrets.token || github.token }}
73+
4574
- name: Finalize release
46-
run: finalize-release "$DRAFT"
75+
id: finalize-release
76+
run: finalize-release "$DRAFT" --archival-path "$CLONE_PATH"
4777
env:
4878
DRAFT: ${{ inputs.draft }}
4979
# Use the other token to allow the aliasing workflow to run
50-
GH_TOKEN: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}
80+
GH_TOKEN: ${{ secrets.token || github.token }}
81+
CLONE_PATH: ${{ steps.set-repo-name.outputs.CLONE_PATH }}

.github/workflows/wf-prepare-release.yaml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,22 @@ on:
2828
required: false
2929
version_files:
3030
type: string
31-
description: Comma-separated list of relative paths to files with version numbers that should be updated. Every file must have exactly one line that looks like `version = "xxxx"` - some effort is made to handle different quoting styles, leading underscores, etc.
31+
description: >
32+
Comma-separated list of relative paths to files with version numbers
33+
that should be updated. Every file must have exactly one line that
34+
looks like `version = "xxxx"` - some effort is made to handle
35+
different quoting styles, leading underscores, etc.
3236
required: false
3337
default: ""
3438

39+
secrets:
40+
token:
41+
description: >
42+
Personal access token (PAT) used to open the pull request. Must be
43+
provided in order for any actions to run in response to the PR
44+
creation.
45+
required: false
46+
3547
jobs:
3648
prepare-release:
3749
runs-on: ubuntu-latest
@@ -50,7 +62,7 @@ jobs:
5062
env:
5163
REPO: ${{ github.repository }}
5264
RUN_ID: ${{ github.run_id }}
53-
GH_TOKEN: ${{ github.token }}
65+
GH_TOKEN: ${{ secrets.token || github.token }}
5466
run: |
5567
ACTION_DATA=$(gh api "repos/$REPO/actions/runs/$RUN_ID")
5668
echo "::debug::$ACTION_DATA"
@@ -63,7 +75,6 @@ jobs:
6375
repository: uclahs-cds/tool-create-release
6476
path: reusable
6577
ref: ${{ steps.workflow-parsing.outputs.SHA }}
66-
token: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}
6778

6879
- name: Checkout calling repository
6980
uses: actions/checkout@v4
@@ -104,7 +115,7 @@ jobs:
104115
- name: Create Pull Request
105116
uses: peter-evans/create-pull-request@v7
106117
with:
107-
token: ${{ secrets.UCLAHS_CDS_REPO_READ_TOKEN }}
118+
token: ${{ secrets.token || github.token }}
108119
path: caller
109120
add-paths: ${{ inputs.changelog }},${{ inputs.version_files }}
110121
commit-message: ${{ steps.bump-changelog.outputs.commit_message }}

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88

9+
## Unreleased
10+
11+
### Added
12+
13+
- Add `attach-tarball` argument to finalize workflow to attach source tarball with release
14+
15+
### Changed
16+
17+
- Remove hard-coded UCLA secrets, add explicit `secrets` inputs to workflows
18+
919
## [1.0.3] - 2024-11-01
1020

1121
### Fixed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Usage of this tool requires adding three workflows to each calling repository (n
4949

5050
1. Create a new release with auto-generated notes and the target tag.
5151
* By default the new release is a draft, so no public release or tag are created without user intervention.
52+
1. Optionally, attach a source tarball including all submodules to the new release.
5253
1. Comment on the release PR with a link to the new release.
5354

5455
```mermaid
@@ -113,7 +114,14 @@ Parameters can be specified using the [`with`](https://docs.github.com/en/action
113114
| `wf-prepare-release.yaml` | `changelog` | string | no | Relative path to the CHANGELOG file. Defaults to `./CHANGELOG.md`. |
114115
| `wf-prepare-release.yaml` | `timezone` | string | no | IANA timezone to use when calculating the current date for the CHANGELOG. Defaults to `America/Los_Angeles`. |
115116
| `wf-finalize-release.yaml` | `draft` | boolean | no | If true (the default), mark the new release as a draft and require manual intervention to continue. |
117+
| `wf-finalize-release.yaml` | `attach-tarball` | boolean | no | If true (not the default), attach a tarball of the repository source, including all submodules, to the release. |
118+
| `wf-alias-release.yaml` | `commit-user-name` | string | no | User name to use while tagging new commits (defaults to `github-actions[bot]`) |
119+
| `wf-alias-release.yaml` | `commit-user-email` | string | no | User email to use while tagging new commits (defaults to `41898282+github-actions[bot]@users.noreply.github.com`) |
116120

121+
All four workflows also accept a `token` secret which is required for full functionality (e.g. CI/CD checks on the opened pull request). The provided [personal access token](https://github.com/settings/tokens/new) should be stored as a secret in the repository and have the following scopes:
122+
123+
* `repo`
124+
* `workflow`
117125

118126
### Updating hard-coded strings with `version_files`
119127

bumpchanges/finalize.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from dataclasses import dataclass, field
1111
from pathlib import Path
12+
from typing import Optional
1213

1314

1415
from .logging import setup_logging, NOTICE, LoggingMixin
@@ -75,7 +76,7 @@ def __post_init__(self):
7576
except ValueError:
7677
pass
7778

78-
def create(self, draft: bool):
79+
def create(self, draft: bool, archival_path: Optional[Path]):
7980
"""Create the release and return the URL."""
8081
args = [
8182
"gh",
@@ -119,6 +120,45 @@ def create(self, draft: bool):
119120
width=2000,
120121
)
121122

123+
# Create and upload a tarball if the archival path exists
124+
if archival_path:
125+
self.logger.info("Creating tarball")
126+
127+
tarball = Path(
128+
os.environ["GITHUB_WORKSPACE"],
129+
f"{archival_path.name}-{self.tag}.tar.gz",
130+
)
131+
132+
subprocess.run(
133+
["tar", "--exclude-vcs", "-czvf", tarball, archival_path.name],
134+
cwd=archival_path.parent,
135+
check=True,
136+
)
137+
138+
try:
139+
subprocess.run(
140+
[
141+
"gh",
142+
"release",
143+
"upload",
144+
self.tag,
145+
"--repo",
146+
self.owner_repo,
147+
f"{tarball}#Source code with submodules (tar.gz)",
148+
],
149+
check=True,
150+
)
151+
comment_body += (
152+
"\n\nA source tarball including all submodules "
153+
"has been attached to the release."
154+
)
155+
156+
except subprocess.CalledProcessError:
157+
self.logger.error("Failed to attach tarball to release!")
158+
comment_body += (
159+
"\n\n**ERROR:** Failed to attach source tarball to release!"
160+
)
161+
122162
subprocess.run(
123163
[
124164
"gh",
@@ -140,15 +180,29 @@ def entrypoint():
140180

141181
parser = argparse.ArgumentParser()
142182
parser.add_argument("draft", type=str_to_bool)
183+
parser.add_argument(
184+
"--archival-path", help="Path to a directory to tar and attach to the release"
185+
)
143186

144187
args = parser.parse_args()
145188

146189
try:
147190
# Parse the environment to create the release
148191
new_release = PreparedRelease.from_environment()
149192

193+
archival_path = Path(args.archival_path) if args.archival_path else None
194+
if archival_path and not archival_path.exists():
195+
archival_path = None
196+
197+
if archival_path:
198+
# Sanity-check that the cloned name matches the environment
199+
repo_name = new_release.owner_repo.split("/", maxsplit=1)[-1]
200+
if repo_name != archival_path.name:
201+
raise RuntimeError(f"{repo_name} != {archival_path.name}!")
202+
150203
# Draft or create the release
151-
new_release.create(args.draft)
204+
new_release.create(args.draft, archival_path)
205+
152206
except:
153207
logging.getLogger(__name__).exception("Failed to create new release")
154208
raise

templates/alias-release.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ permissions:
1616
jobs:
1717
update-alias:
1818
uses: uclahs-cds/tool-create-release/.github/workflows/wf-alias-release.yaml@v1
19-
secrets: inherit
19+
secrets:
20+
token: ${{ secrets.YOUR_PAT }}

0 commit comments

Comments
 (0)