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

Version selection: add AWS redirect configs for latest docs version #561

Merged
merged 10 commits into from
Apr 6, 2022
10 changes: 2 additions & 8 deletions .github/workflows/deploy-book.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,13 @@ jobs:
if [[ $GITHUB_REF =~ ^refs/heads/(master|[0-9][0-9.]+)$ ]]; then
echo "::set-output name=branch::${BASH_REMATCH[1]}"
fi
- name: Build versions file
if: github.event_name == 'push' && steps.branch.outputs.branch != null
run: scripts/docs-versions.sh origin | tee /dev/stderr > versions.json
- name: Configure AWS Credentials
if: github.event_name == 'push' && steps.branch.outputs.branch != null
if: github.event_name == 'push' && steps.branch.outputs.branch != null && github.repository == 'crystal-lang/crystal-book'
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy book
if: github.event_name == 'push' && steps.branch.outputs.branch != null
if: github.event_name == 'push' && steps.branch.outputs.branch != null && github.repository == 'crystal-lang/crystal-book'
run: aws s3 sync ./site s3://crystal-book/reference/${{ steps.branch.outputs.branch }} --delete
- name: Deploy versions file
if: github.event_name == 'push' && steps.branch.outputs.branch != null
run: aws s3 sync . s3://crystal-book/reference --exclude '*' --include 'versions.json'
33 changes: 33 additions & 0 deletions .github/workflows/deploy-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Deploy config
on:
- create
- delete
Copy link
Member Author

Choose a reason for hiding this comment

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

Hm is it possible to limit the range of branches that trigger this?

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately, no. These events are global and unfiltered.

I suppose we could filter for version branches in the steps. I think ${ github.event.ref } should hold the name of the branch (or tag) that was created or deleted.
Per https://docs.github.com/en/actions/learn-github-actions/contexts and https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#create

Maybe it would also be a viable alternative to not automate this in this repo, but integrate the steps with the release workflow over in https://github.com/crystal-lang/distribution-scripts (see https://github.com/crystal-lang/distribution-scripts/blob/master/processes/crystal-release.md)

Copy link
Member

Choose a reason for hiding this comment

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

The addition of a new branch (like when we release 1.3) needs to be triggered somehow. At that point we can also update the versions and website configuration.

Deletion is probably not even worth automating. That should never happen and if it does, it's because of manual interference.

Copy link
Member

Choose a reason for hiding this comment

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

Thinking about this again, I think we should have all the configuration-level changes manually triggered (maybe it can be automatically triggered as part of the release process at some point, but that's not super important).

The workflow could go like this:

  1. Checkout https://github.com/crystal-lang/crystal-book
  2. Create a new version branch from master and push it
  3. Wait for deployment
  4. Update latest redirects (S3 bucket website configuration) and versions.json

https://github.com/crystal-lang/distribution-scripts/ seems like a good place for that because we have everything else already collected there.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't see much advantage to making it manually triggered (The creation of a branch in this repo is already a manual action BTW), but doesn't matter much to me. I agree with your idea.

This part is not critical for the moment, but clearly the way to proceed is to make a PR on distribution-scripts with these same scripts but slightly adapted. I am personally not interested in contributing to distribution-scripts but let me know if you think it's best that I do that.

And out of this PR only the change to .github/workflows/deploy-book.yml needs to be kept. But that should be applied after the other side (distribution-scripts) is finalized.


jobs:
build:
name: Deploy config
runs-on: ubuntu-latest
env:
S3_BUCKET: crystal-book
steps:
- name: Download source
uses: actions/checkout@v2
- name: Build versions.json
run: scripts/docs-versions.sh origin | tee /dev/stderr > versions.json
- name: Build aws-config.json
run: |
latest_version=$(git ls-remote --heads origin | grep -P -o '(?<=refs/heads/)[0-9][0-9.]+' | sort -V -r | head -n1)
Copy link
Member Author

Choose a reason for hiding this comment

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

So now we have this git ls-remote code in two places. I don't understand what the trouble was to keep this code snippet within the script itself. Can I change it back?

Copy link
Member

Choose a reason for hiding this comment

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

It's different concerns. I'd like that to be separate processes. The current implementation closely resembles the setup we're already using for the API docs over at https://github.com/crystal-lang/distribution-scripts/blob/8328ae59292c05cf8c830a34b5b39ac46c43813e/docs/Makefile#L43-L55
I'm sure we can remove the duplicate invocation by caching the result in an output variable.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not different concerns, though. It is exactly the same concern - "make versions up to date", just that AWS happens to handle one side of it separately.

Copy link
Member Author

Choose a reason for hiding this comment

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

Consider that both sides of this operation mainly change the meaning of "latest" - one for MkDocs and one for AWS. They shouldn't be separated.

Copy link
Member Author

Choose a reason for hiding this comment

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

With this in mind, I added back some of my refactors. Sorry for the trouble and I realize it's kinda rude.
We can definitely keep discussing this and change back still.

sed 's/\${LATEST_VERSION}/${latest_version}/g' scripts/aws-config.json | tee /dev/stderr > aws-config.json
- name: Configure AWS Credentials
if: github.repository == 'crystal-lang/crystal-book'
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy versions.json
if: github.repository == 'crystal-lang/crystal-book'
run: aws s3 cp versions.json "s3://${{ env.S3_BUCKET }}/reference/versions.json"
- name: Deploy website configuration
if: github.repository == 'crystal-lang/crystal-book'
run: aws s3api put-bucket-website --bucket "${{ env.S3_BUCKET }}" --website-configuration "file://aws-config.json"
77 changes: 77 additions & 0 deletions scripts/aws-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"IndexDocument": {
"Suffix": "index.html"
},
"ErrorDocument": {
"Key": "reference/404.html"
},
"RoutingRules": [
{
"Condition": {
"KeyPrefixEquals": "reference/installation"
},
"Redirect": {
"HostName": "crystal-lang.org",
"HttpRedirectCode": "301",
"Protocol": "https",
"ReplaceKeyPrefixWith": "install"
}
},
{
"Condition": {
"KeyPrefixEquals": "reference/overview/hello_world.html"
oprypin marked this conversation as resolved.
Show resolved Hide resolved
},
"Redirect": {
"HostName": "crystal-lang.org",
"HttpRedirectCode": "301",
"Protocol": "https",
"ReplaceKeyPrefixWith": "reference/getting_started"
}
},
{
"Condition": {
"KeyPrefixEquals": "reference/overview"
},
"Redirect": {
"HostName": "crystal-lang.org",
"HttpRedirectCode": "301",
"Protocol": "https",
"ReplaceKeyPrefixWith": "reference/getting_started"
}
},
{
"Condition": {
"KeyPrefixEquals": "reference/${LATEST_VERSION}/${LATEST_VERSION}/"
},
"Redirect": {
"HostName": "crystal-lang.org",
"HttpRedirectCode": "301",
"Protocol": "https",
"ReplaceKeyWith": "404"
}
},
oprypin marked this conversation as resolved.
Show resolved Hide resolved
{
"Condition": {
"KeyPrefixEquals": "reference/latest"
},
"Redirect": {
"HostName": "crystal-lang.org",
"HttpRedirectCode": "302",
"Protocol": "https",
"ReplaceKeyPrefixWith": "reference/${LATEST_VERSION}/"
}
},
{
"Condition": {
"HttpErrorCodeReturnedEquals": "404",
"KeyPrefixEquals": "reference/"
},
"Redirect": {
"HostName": "crystal-lang.org",
"HttpRedirectCode": "301",
"Protocol": "https",
"ReplaceKeyPrefixWith": "reference/${LATEST_VERSION}/"
}
}
]
}
17 changes: 10 additions & 7 deletions scripts/docs-versions.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#!/usr/bin/env sh
set -e
#!/bin/bash
set -eu

printf '['
branches=( $(git ls-remote --heads "${1:-.}" | grep -P -o '(?<=refs/heads/)[0-9][0-9.]+' | sort -V -r) )
latest_branch="${branches[0]}"

printf '[\n'
latest='"latest"'
for ver in $(git ls-remote --heads "${1:-.}" | grep -P -o '(?<=refs/heads/)[0-9][0-9.]+' | sort -V -r); do
printf '{"version": "%s", "title": "%s", "aliases": [%s]}, ' "$ver" "$ver" "$latest"
for ver in "${branches[@]}"; do
printf '{"version": "%s", "title": "%s", "aliases": [%s]},\n' "$ver" "$ver" "$latest"
latest=''
done
printf '{"version": "master", "title": "nightly", "aliases": []}'
printf ']'
printf '{"version": "master", "title": "nightly", "aliases": []}\n'
printf ']\n'
test -z "$latest" # Check that we wrote at least one version