(production) AI Search, Project Tracker, Accessibility #20
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @file: D10-Publish.yml | |
# This Action clones the current private repo, sanitizes it (removes potentially | |
# secrets-containing files) and then commits resultant files to the Public repo. | |
# - This Action is fired when the production branch has code pushed to it, | |
# this is typically when: | |
# 1. a PR to the production branch is committed, or | |
# 2. a commit is pushed and merged directly into the production branch, or | |
# 3. (maybe) any other activity which alters the code at the HEAD of the | |
# production branch or moves the HEAD of the branch. | |
# Several actions to make Release Notes and Tags cascade on completion of this | |
# workflow. | |
# - d10-GeneratePrivateRelease.yml | |
# - d10-GeneratePublicRelease.yml | |
# Attached resources: | |
# - GitHub SECRETS: | |
# -> local: PUBLIC_REPO_TARGET -> The public repoistory fmt CityOfBoston/xxxx | |
# -> global.PUBLIC_REPO_TARGET_BRANCH -> Branch to push to in the | |
# -> global.PUBLISH_GITHUB_TOKEN -> GitHub token used for gh cli and auth for private repos | |
# -> global: SLACK_DOIT_WEBHOOK_URL -> Webhook URL for posting messages to slack | |
# - GitHub VARIABLES: | |
# => INTERNAL VARS | |
# -> local.SLACK_MONITORING_CHANNEL -> Channel for failure notices | |
# -> local.DEBUG -> Control flag to denote in debug mode (output extra info) | |
# -> local.DRY_RUN -> Stops changes being passed back to GitHub | |
# -> local.COUNT -> A counter used to create unique sequential RELEASE numbers | |
# => VARS SHARED WITH OUTHER WORKFLOWS | |
# -> local.LAST_TAG -> Records The previous tag used to tag the private repo | |
# -> local.THIS_TAG -> Records The tag used to tag the private repo for this publish | |
# -> local.THIS_RELEASE -> Records the release number for this publish | |
# -> local.THIS_TITLE -> Records the Pull Request title | |
# -> local.THIS_BODY -> Records the Pull Request body text | |
name: "Publish to Public Repo" | |
on: | |
workflow_dispatch: | |
pull_request: | |
types: | |
- closed | |
branches: | |
- production | |
env: | |
GITHUB_TOKEN: ${{ secrets.PUBLISH_GITHUB_TOKEN }} | |
DEV_EMAIL: "digital-dev@boston.gov" | |
PR_USER: ${{ github.event.pull_request.merged_by.login }} | |
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_DOIT_WEBHOOK_URL }} # for slack | |
jobs: | |
Publish: | |
# Only run is the PR has been merged and closed (not just closed) or DEBUG. | |
if: github.event.pull_request.merged == true || vars.DEBUG == 1 | |
# installed software: https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
permissions: | |
# Give the default GITHUB_TOKEN write permission to commit and push the | |
# added or changed files to the repository. | |
contents: write | |
steps: | |
# Checkout this (private) repository into local "private" folder. | |
- name: Checkout (this) Private repository into local "private" folder. | |
id: Checkout-Private-Repo | |
uses: actions/checkout@v4 | |
with: | |
path: private | |
fetch-depth: 0 # 0 = all - otherwise, will likely fail to push tags to dest repo | |
- name: Debug event context | |
if: ${{ vars.DEBUG == 1 }} | |
env: | |
EVENT_CONTEXT: ${{ toJSON(github.event) }} | |
run: | | |
echo $EVENT_CONTEXT | |
# | |
# Create and save some variables for use in the cascading actions. | |
# Set them here, so they can be simply read by the other actions, and we | |
# can (try to) make sure our tags align with Acquia tags. | |
- name: Set environment variables | |
run: | | |
cd private | |
count=0 | |
ACQUIA_TAG=$(date +tags/%Y-%m-%d) | |
while [[ $(git tag --list | grep $ACQUIA_TAG) ]]; do | |
ACQUIA_TAG=$(date +tags/%Y-%m-%d).$count | |
count=$(($count+1)) | |
ok=$(git tag --list | grep $ACQUIA_TAG) || break | |
[[ $count -gt 10 ]] && exit 100 | |
done | |
echo "THIS_TAG=\"$ACQUIA_TAG\"" >> "${GITHUB_ENV}" | |
echo "THIS_RELEASE=\"v10.$(date +%Y).${{ vars.COUNT }}\"" >> "${GITHUB_ENV}" | |
# | |
# Clone the Public Repository and checkout branch | |
- name: Checkout Public repository | |
id: Checkout-Public-Repo | |
run: | | |
[[ ${{ vars.DEBUG }} == 1 ]] && echo "ssh-key-file: ${HOME}/.ssh/id_rsa" && echo "ssh-key-path: ${HOME}/.ssh" | |
mkdir -p ${HOME}/.ssh | |
echo "${{ secrets.SSH_GITHUB_KEY }}" > "${HOME}/.ssh/id_rsa" | |
chmod 600 ${HOME}/.ssh/id_rsa | |
git config --global --add core.sshCommand "ssh -i ${HOME}/.ssh/id_rsa" | |
echo "git clone ${{ secrets.PUBLIC_REPO_TARGET }} --depth=10 --branch=${{ secrets.PUBLIC_REPO_TARGET_BRANCH }} publish" | |
git clone ${{ secrets.PUBLIC_REPO_TARGET }} --depth=10 --branch=${{ secrets.PUBLIC_REPO_TARGET_BRANCH }} publish | |
cd publish | |
git fetch origin ${{ secrets.PUBLIC_REPO_TARGET_BRANCH }} | |
git reset --hard FETCH_HEAD | |
# | |
# Sanitize the code in the local "private" folder | |
- name: Sanitize Repository | |
id: Sanitize-Repository | |
env: | |
publish_from_file: ${{ github.workspace }}/private/.github/sanitize/publish-from.txt | |
publish_excludes_file: ${{ github.workspace }}/private/.github/sanitize/publish-excludes.txt | |
run: | | |
err="" | |
cd private | |
rsync -rlDWz --max-size=10m --files-from=${publish_from_file} --exclude-from=${publish_excludes_file} --delete-after . ../publish && echo "Copied updated codebase" || err="Error copying updated codebase" | |
mv -f ../publish/README.PUBLIC.md ../publish/README.md || echo "WARNING: could not create README.md" | |
mv -f ../publish/LICENSE.PUBLIC.md ../publish/LICENSE.md || echo "WARNING: could not create LICENSE.md" | |
[[ "$( git status --porcelain --untracked-files=no --ignored=no )" == "" ]] && echo "changes=0" >> "$GITHUB_OUTPUT" || echo "changes=1" >> "$GITHUB_OUTPUT" | |
if [[ "$err" != "" ]]; then | |
echo "::error file=D10-Publish.yml,title=Error,line=139::$err" | |
exit 1 | |
fi | |
# | |
# Tag and push tag to private repository | |
- name: Tag the Private Repo branch | |
run: | | |
cd private | |
git config --global user.email "${{ env.DEV_EMAIL }}" | |
if [[ -z "${{ env.PR_USER }}" ]]; then | |
git config --global user.name "Guthub Publish Action" | |
else | |
git config --global user.name "${{ env.PR_USER }}" | |
fi | |
git tag -a "${{ env.THIS_TAG }}" -m "${{ env.THIS_RELEASE }}" | |
[ ${{ vars.DRY_RUN }} == 0 ] && git push origin ${{ env.THIS_TAG }} || echo "Tagging DRY_RUN mode" | |
# | |
# Commit and push latest code to Public repository | |
- name: Tag and Push to the Public Repo | |
run: | | |
cd publish | |
err='' | |
git config --global user.email ${{ env.DEV_EMAIL }} | |
if [[ -z "${{ env.PR_USER }}" ]]; then | |
git config --global user.name "Guthub Publish Action" | |
else | |
git config --global user.name "${{ env.PR_USER }}" | |
fi | |
git submodule deinit --all || err="$err: Could not de-initialize submodules" | |
if [[ ${{ vars.DEBUG }} == 1 ]]; then | |
echo "Working Tree Status (pre-add&commit):" | |
git status | |
fi | |
git add --all && echo ' ' || err="$err: Failed to add changed files" | |
[[ ${{ vars.DEBUG }} == 1 ]] && commitopt="--status" || commitopt="--quiet" | |
commitopt="$commitopt --no-verify --signoff" | |
res=$(git commit -m '${{ github.event.pull_request.title }}' $commitopt) || err="$err: Problem committing changes" | |
pushopts="--force" | |
if [[ ${{ vars.DEBUG }} == 1 ]]; then | |
echo "Working Tree Status (post-add&commit):" | |
git status -s | |
echo "Commit results:" && echo $res | |
pushopts="$pushopts --verbose" | |
fi | |
[[ ${{ vars.DRY_RUN }} == 1 ]] && pushopts="$pushopts --dry-run" | |
if [[ $(echo "$res" | grep "nothing to commit") == "" ]]; then | |
echo "changes=1" >> "$GITHUB_OUTPUT" | |
echo "git push --set-upstream origin ${{ secrets.PUBLIC_REPO_TARGET_BRANCH }}:${{ secrets.PUBLIC_REPO_TARGET_BRANCH }} ${pushopts}" | |
git push --set-upstream origin ${{ secrets.PUBLIC_REPO_TARGET_BRANCH }}:${{ secrets.PUBLIC_REPO_TARGET_BRANCH }} ${pushopts} || err="$err: Problem pushing changes to Public Repo" | |
git tag -a "${{ env.THIS_TAG }}" -m "${{ env.THIS_RELEASE }}" | |
echo "git push origin ${{ env.THIS_TAG }}" | |
git push origin ${{ env.THIS_TAG }} | |
if [[ ${{ vars.DRY_RUN }} == 0 ]]; then | |
echo "::notice file=D10-Publish.yml,title=Success::Public repository was updated." | |
else | |
echo "::notice file=D10-Publish.yml,title=Success::Public repository was not updated because this was a dry-run." | |
fi | |
else | |
echo "changes=0" >> "$GITHUB_OUTPUT" | |
echo "::notice file=D10-Publish.yml,title=No Changes::No changes were found to be pushed to Public repository." | |
fi | |
if [[ "$err" != "" ]]; then | |
echo "::error file=D10-Publish,title=Error,line=213::$err" | |
exit 1 | |
fi | |
# | |
# On success, save GitHub variables for future use. | |
- name: Update Variables on success | |
if: ${{ success() && vars.DRY_RUN == 0 }} | |
env: | |
GH_TOKEN: ${{ secrets.PUBLISH_GITHUB_TOKEN }} | |
run: | | |
cd private | |
gh variable set LAST_TAG --body "${{ vars.THIS_TAG }}" | |
gh variable set LAST_RELEASE --body "${{ vars.THIS_RELEASE }}" | |
gh variable set COUNT --body $(( ${{ vars.COUNT }}+1 )) | |
gh variable set THIS_TAG --body "${{ env.THIS_TAG }}" | |
gh variable set THIS_RELEASE --body "${{ env.THIS_RELEASE }}" | |
gh variable set THIS_TITLE --body "${{ github.event.pull_request.title }}" | |
gh variable set THIS_BODY --body "${{ github.event.pull_request.body }}" | |
# | |
# If failure, post to slack. | |
- name: Post to Slack - failure | |
uses: act10ns/slack@v2.0.0 | |
if: ${{ failure() }} | |
with: | |
status: ${{ job.status }} | |
steps: ${{ toJson(steps) }} | |
channel: ${{ vars.SLACK_MONITORING_CHANNEL }} | |
message: There were issues publishing to the Public Repo {{workflowRunUrl}} |