Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up release tag mapping workflow. #17801

Merged
merged 3 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# GENERATED, DO NOT EDIT!
# To change, edit `build-support/bin/generate_github_workflows.py` and run:
# ./pants run build-support/bin/generate_github_workflows.py


jobs:
publish-tag-to-commit-mapping:
if: github.repository_owner == 'pantsbuild'
runs-on: ubuntu-latest
steps:
- env:
TAG: ${{ github.event.inputs.tag }}
id: determine-tag
name: Determine Release Tag
run: "if [[ -n \"$TAG\" ]]; then\n tag=\"$TAG\"\nelse\n tag=\"${GITHUB_REF#refs/tags/}\"\
\nfi\nif [[ \"${tag}\" =~ ^release_.+$ ]]; then\n echo \"release-tag=${tag}\"\
\ >> $GITHUB_OUTPUT\nelse\n echo \"::error::Release tag '${tag}' must match\
\ 'release_.+'.\"\n exit 1\nfi\n"
- name: Checkout Pants at Release Tag
uses: actions/checkout@v3
with:
ref: ${{ steps.determine-tag.outputs.release-tag }}
- name: Create Release -> Commit Mapping
run: 'tag="${{ steps.determine-tag.outputs.release-tag }}"


# Tricky syntax, but correct. The literal suffix `^{commit}` gets

# the sha of the commit object that is the tag''s target (as opposed

# to the sha of the tag object itself).

commit="$(git rev-parse ${tag}^{commit})"


echo "Recording tag ${tag} is of commit ${commit}"

mkdir -p dist/deploy/tags/pantsbuild.pants

echo "${commit}" > "dist/deploy/tags/pantsbuild.pants/${tag}"

'
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
name: Deploy to S3
run: ./build-support/bin/deploy_to_s3.py
name: Record Release Commit
'on':
push:
tags:
- release_*
workflow_dispatch:
inputs:
tag:
required: true
type: string
81 changes: 79 additions & 2 deletions build-support/bin/generate_github_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ def install_go() -> Step:
}


def deploy_to_s3() -> Step:
def deploy_to_s3(when: str = "github.event_name == 'push'") -> Step:
return {
"name": "Deploy to S3",
"run": "./build-support/bin/deploy_to_s3.py",
"if": "github.event_name == 'push'",
"if": when,
"env": {
"AWS_SECRET_ACCESS_KEY": f"{gha_expr('secrets.AWS_SECRET_ACCESS_KEY')}",
"AWS_ACCESS_KEY_ID": f"{gha_expr('secrets.AWS_ACCESS_KEY_ID')}",
Expand Down Expand Up @@ -799,6 +799,69 @@ def cache_comparison_jobs_and_inputs() -> tuple[Jobs, dict[str, Any]]:
return jobs, cc_inputs


def release_jobs_and_inputs() -> tuple[Jobs, dict[str, Any]]:
inputs, env = workflow_dispatch_inputs([WorkflowInput("TAG", "string")])

jobs = {
"publish-tag-to-commit-mapping": {
"runs-on": "ubuntu-latest",
"if": IS_PANTS_OWNER,
"steps": [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use these 1st two steps in Pex, the a-scie projects and several other pantsbuild projects. Pretty well tested.

{
"name": "Determine Release Tag",
"id": "determine-tag",
"env": env,
"run": dedent(
"""\
if [[ -n "$TAG" ]]; then
tag="$TAG"
else
tag="${GITHUB_REF#refs/tags/}"
fi
if [[ "${tag}" =~ ^release_.+$ ]]; then
echo "release-tag=${tag}" >> $GITHUB_OUTPUT
else
echo "::error::Release tag '${tag}' must match 'release_.+'."
exit 1
fi
"""
),
},
{
"name": "Checkout Pants at Release Tag",
"uses": "actions/checkout@v3",
"with": {"ref": f"{gha_expr('steps.determine-tag.outputs.release-tag')}"},
},
{
"name": "Create Release -> Commit Mapping",
# N.B.: The "literal suffix" mentioned below will only be the actual correct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I found this note more confusing than clarifying. Maybe the comment below (the sentence after "Tricky syntax, but correct.") can use single braces (and link to https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltrevgtlttypegtemegemv0998commitem ?)

The reader will understand that the double braces are for escaping .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, dammit, the double-braces are needed in the comment so that it renders in the yaml comment. I see what you were doing with the code comment... I still found it confusing at first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this can all be a code comment? We don't render yaml comments anywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sounds good - lifted the comment out of the yaml.

# literal syntax on rendering of the yaml document - confusing. That literal
# suffix syntax is `^{commit}`.
"run": dedent(
f"""\
tag="{gha_expr("steps.determine-tag.outputs.release-tag")}"

# Tricky syntax, but correct. The literal suffix `^{{commit}}` gets
# the sha of the commit object that is the tag's target (as opposed
# to the sha of the tag object itself).
commit="$(git rev-parse ${{tag}}^{{commit}})"

echo "Recording tag ${{tag}} is of commit ${{commit}}"
mkdir -p dist/deploy/tags/pantsbuild.pants
echo "${{commit}}" > "dist/deploy/tags/pantsbuild.pants/${{tag}}"
"""
),
},
deploy_to_s3(
when="github.event_name == 'push' || github.event_name == 'workflow_dispatch'"
),
],
}
}

return jobs, inputs


# ----------------------------------------------------------------------
# Main file
# ----------------------------------------------------------------------
Expand Down Expand Up @@ -975,12 +1038,26 @@ def generate() -> dict[Path, str]:
Dumper=NoAliasDumper,
)

release_jobs, release_inputs = release_jobs_and_inputs()
release_yaml = yaml.dump(
{
"name": "Record Release Commit",
"on": {
"push": {"tags": ["release_*"]},
"workflow_dispatch": {"inputs": release_inputs},
},
"jobs": release_jobs,
},
Dumper=NoAliasDumper,
)

return {
Path(".github/workflows/audit.yaml"): f"{HEADER}\n\n{audit_yaml}",
Path(".github/workflows/cache_comparison.yaml"): f"{HEADER}\n\n{cache_comparison_yaml}",
Path(".github/workflows/cancel.yaml"): f"{HEADER}\n\n{cancel_yaml}",
Path(".github/workflows/test.yaml"): f"{HEADER}\n\n{test_yaml}",
Path(".github/workflows/test-cron.yaml"): f"{HEADER}\n\n{test_cron_yaml}",
Path(".github/workflows/release.yaml"): f"{HEADER}\n\n{release_yaml}",
}


Expand Down