Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
28 changes: 22 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -262,18 +262,34 @@ jobs:

- name: Commit, push and tag the provider
env:
PUSH_TOKEN: ${{ secrets.TF_PROVIDER_GITHUB_TOKEN }}
# A deploy key with write access to terraform-provider-logstruct only. Deploy keys don't expire: the PAT
# this replaced had expired by the 0.2.0 release.
DEPLOY_KEY: ${{ secrets.TF_PROVIDER_DEPLOY_KEY }}
run: |
if [[ -z "$DEPLOY_KEY" ]]; then
echo "::error::TF_PROVIDER_DEPLOY_KEY isn't set in the release environment."
exit 1
fi
mkdir -p ~/.ssh && chmod 700 ~/.ssh
printf '%s\n' "$DEPLOY_KEY" > ~/.ssh/provider_deploy_key
chmod 600 ~/.ssh/provider_deploy_key
# GitHub's published host keys, so the key is only ever offered to github.com
curl -fsS https://api.github.com/meta | jq -r '.ssh_keys[] | "github.com " + .' > ~/.ssh/github_known_hosts
export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/provider_deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=$HOME/.ssh/github_known_hosts"
REMOTE=git@github.com:DocSpring/terraform-provider-logstruct.git
# Stop before changing anything if GitHub doesn't accept the key
if ! git ls-remote "$REMOTE" HEAD >/dev/null; then
echo "::error::GitHub didn't accept TF_PROVIDER_DEPLOY_KEY for terraform-provider-logstruct: check the repo's deploy key (with write access) matches the secret."
exit 1
fi
git config --global user.name "DocSpring Bot"
git config --global user.email "docspring-bot@docspring.com"
git clone https://github.com/DocSpring/terraform-provider-logstruct.git terraform-provider-logstruct
git clone "$REMOTE" terraform-provider-logstruct
cd terraform-provider-logstruct
# The token is passed to the two pushes only, not stored in the clone's config
AUTH="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$PUSH_TOKEN" | base64 -w0)"
if [[ -s ../provider-changes.patch ]]; then
git apply --index ../provider-changes.patch
git commit -m "Sync catalog from logstruct $TAG_NAME"
git -c "http.https://github.com/.extraheader=$AUTH" push origin HEAD:main
git push origin HEAD:main
else
echo "No provider changes to commit."
fi
Expand All @@ -282,4 +298,4 @@ jobs:
exit 0
fi
git tag -a "$TAG_NAME" -m "Release $TAG_NAME (logstruct sync)"
git -c "http.https://github.com/.extraheader=$AUTH" push origin "$TAG_NAME"
git push origin "$TAG_NAME"
8 changes: 6 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,12 @@ For template file changes (tests, rake tasks, etc.), just run `scripts/rails_tes

## Required secrets

- `TF_PROVIDER_GITHUB_TOKEN` (a `release` environment secret): PAT with write access to
`DocSpring/terraform-provider-logstruct` for syncing/tagging.
- `TF_PROVIDER_DEPLOY_KEY` (a `release` environment secret): the private half of a deploy key with write access to
`DocSpring/terraform-provider-logstruct`, for syncing and tagging it. To replace it, generate an ed25519 key, add the
public half as a write deploy key on the provider repo and set the private half as this secret.
- The provider repo's own release (GoReleaser, on its `v*` tags) signs with the GPG key in its `GPG_PRIVATE_KEY`
secret. The Terraform Registry only accepts releases signed by a key registered for the DocSpring namespace, so a
new signing key must be added to the registry before the next provider release.
- RubyGems needs no secret: the `logstruct` gem has a trusted publisher for this repository's Release workflow and its
`release` environment.

Expand Down
10 changes: 10 additions & 0 deletions test/workflows/release_workflow_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,15 @@ def all_needs(job_id)

assert_equal({"publish_gem" => "release", "publish_provider" => "release"}, environments)
end

test "the provider push uses the deploy key and checks it before changing anything" do
steps = jobs.fetch("publish_provider").fetch("steps")
env = steps.filter_map { |step| step["env"] }.reduce({}, :merge)
run = steps.map { |step| step["run"].to_s }.join("\n")

assert_equal "${{ secrets.TF_PROVIDER_DEPLOY_KEY }}", env["DEPLOY_KEY"]
refute_match(/TF_PROVIDER_GITHUB_TOKEN|x-access-token/, run)
assert_operator run.index("git ls-remote"), :<, run.index("git clone")
end
end
end