Skip to content

release holochain

release holochain #11

Workflow file for this run

# Contained Jobs
# - vars: processes the input
# - prepare: imported from ./release-prepare.yml
# - test: currently unimplemented
# - finalize:
# - restore repo from cache
# - push to the target branch
# - push to the release branch (TODO: What is the difference)
# - publish crates
# - push tags
# - merge release branch into source branch
# - push updated source branch
# - create a pull-request towards the source branch
# - create a github release
name: release holochain
on:
schedule:
- cron: "0 0 * * 3" # at 0 AM on wednesday
workflow_dispatch:
inputs:
# holochain_url:
# description: "holochain git repo url"
# required: false
# default: ""
# type: string
holochain_source_branch:
description: "holochain source branch for the release"
required: false
default: ""
type: string
holochain_target_branch:
description: "holochain target branch for the release"
required: false
default: ""
type: string
dry_run:
description: "dry-run: prevent crate.io publishing and pushing the git tags, target and source branches"
required: false
default: "true"
type: string
debug:
description: "start an ssh session on failure"
required: false
default: "true"
type: string
skip_test:
description: "skip the integration test suite"
required: false
default: "false"
type: string
skip_prepare_logic:
description: "skip the version bump step"
type: string
default: "false"
required: true
force_cancel_in_progress:
description: "force cancelling a running action"
required: false
default: "false"
type: string
pull_request: {}
concurrency:
group: release-${{ github.ref_name }}-${{ github.event_name }}
cancel-in-progress: ${{ github.event.inputs.force_cancel_in_progress == 'true' || github.event_name == 'pull_request' }}
env:
HOLOCHAIN_REPO: "/var/tmp/holochain_repo"
CACHIX_REV: "v1.2"
jobs:
vars:
runs-on: ubuntu-latest
outputs:
HOLOCHAIN_REPO: ${{ steps.eval.outputs.HOLOCHAIN_REPO }}
CACHIX_REV: ${{ steps.eval.outputs.CACHIX_REV}}
# holochain_url: ${{ steps.eval.outputs.holochain_url }}
holochain_source_branch: ${{ steps.eval.outputs.holochain_source_branch }}
holochain_target_branch: ${{ steps.eval.outputs.holochain_target_branch }}
dry_run: ${{ steps.eval.outputs.dry_run }}
debug: ${{ steps.eval.outputs.debug }}
skip_test: ${{ steps.eval.outputs.skip_test }}
skip_prepare_logic: ${{ steps.eval.outputs.skip_prepare_logic }}
steps:
- name: evaluate variables
id: eval
env:
# input_holochain_url: ${{ github.event.inputs.holochain_url }}
input_holochain_source_branch: ${{ github.event.inputs.holochain_source_branch }}
input_holochain_target_branch: ${{ github.event.inputs.holochain_target_branch }}
input_dry_run: ${{ github.event.inputs.dry_run}}
input_debug: ${{ github.event.inputs.debug }}
input_skip_test: ${{ github.event.inputs.skip_test }}
input_skip_prepare_logic: ${{ github.event.inputs.skip_prepare_logic }}
run: |
set -xeu
# if [[ ${input_holochain_url} != "" ]]; then
# echo "holochain_url=${input_holochain_url}" >> $GITHUB_OUTPUT
# else
# echo "holochain_url=https://github.com/holochain/holochain" >> $GITHUB_OUTPUT
# fi
if [[ ${input_holochain_source_branch} != "" ]]; then
export holochain_source_branch="${input_holochain_source_branch}"
else
export holochain_source_branch="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
fi
echo "holochain_source_branch=${holochain_source_branch}" >> $GITHUB_OUTPUT
if [[ ${input_holochain_target_branch} != "" ]]; then
echo "holochain_target_branch=${input_holochain_target_branch}" >> $GITHUB_OUTPUT
else
case "${holochain_source_branch}" in
develop*)
echo "holochain_target_branch=$(echo ${holochain_source_branch} | sed 's/^develop/main/')" >> $GITHUB_OUTPUT
;;
*)
echo "holochain_target_branch=release-target-${holochain_source_branch}" >> $GITHUB_OUTPUT
export enforce_dry_run="true"
;;
esac
fi
if [[ "${enforce_dry_run:-false}" == "true" ]]; then
echo dry-run enforced
echo "dry_run=true" >> $GITHUB_OUTPUT
elif [[ ${input_dry_run} != "" ]]; then
echo "dry_run=${input_dry_run}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "schedule" ]]; then
echo "dry_run=false" >> $GITHUB_OUTPUT
else
echo "dry_run=true" >> $GITHUB_OUTPUT
fi
if [[ ${input_debug} != "" ]]; then
echo "debug=${input_debug}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "schedule" ]]; then
echo "debug=false" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "debug=false" >> $GITHUB_OUTPUT
else
echo "debug=true" >> $GITHUB_OUTPUT
fi
if [[ ${input_skip_test} != "" ]]; then
echo "skip_test=${input_skip_test}" >> $GITHUB_OUTPUT
else
echo "skip_test=false" >> $GITHUB_OUTPUT
fi
if [[ ${input_skip_prepare_logic} != "" ]]; then
echo "skip_prepare_logic=${input_skip_prepare_logic}" >> $GITHUB_OUTPUT
else
echo "skip_prepare_logic=false" >> $GITHUB_OUTPUT
fi
echo "HOLOCHAIN_REPO=${{ env.HOLOCHAIN_REPO }}" >> $GITHUB_OUTPUT
echo "CACHIX_REV=${{ env.CACHIX_REV }}" >> $GITHUB_OUTPUT
prepare:
needs: [vars]
uses: ./.github/workflows/release-prepare.yml
with:
dry_run: ${{ needs.vars.outputs.dry_run }}
debug: ${{ needs.vars.outputs.debug }}
skip_prepare_logic: ${{ needs.vars.outputs.skip_prepare_logic }}
HOLOCHAIN_SOURCE_BRANCH: ${{ needs.vars.outputs.holochain_source_branch }}
HOLOCHAIN_TARGET_BRANCH: ${{ needs.vars.outputs.holochain_target_branch }}
HOLOCHAIN_REPO: ${{ needs.vars.outputs.HOLOCHAIN_REPO }}
CACHIX_REV: ${{ needs.vars.outputs.CACHIX_REV }}
secrets:
CACHIX_SIGNING_KEY: ${{ secrets.CACHIX_AUTH_TOKEN }}
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
HRA_GITHUB_TOKEN: ${{ secrets.HRA_GITHUB_TOKEN}}
test:
needs: [vars, prepare]
if: ${{ needs.vars.outputs.skip_test != 'true' }}
uses: ./.github/workflows/holochain-build-and-test.yml
with:
repo_path: ${{ needs.prepare.outputs.repo_nix_store_path }}
finalize:
if: ${{ always() && needs.prepare.result == 'success' && (needs.test.result == 'success' || needs.test.result == 'skipped') && github.event_name != 'pull_request' && (needs.prepare.outputs.releasable_crates == 'true' || needs.vars.outputs.skip_prepare_logic == 'true') }}
needs: [vars, prepare, test]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install nix
uses: cachix/install-nix-action@v20
- name: Setup cachix
uses: cachix/cachix-action@v12
if: ${{ ! contains(matrix.platform.runs-on, 'self-hosted') }}
with:
name: holochain-ci
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
installCommand: |
nix-env -if https://github.com/cachix/cachix/tarball/${CACHIX_REV} \
--substituters 'https://cache.nixos.org https://cachix.cachix.org' \
--trusted-public-keys 'cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY='
- name: Restore the holochain release repository
env:
HOLOCHAIN_REPO_NIX_STORE_PATH: ${{ needs.prepare.outputs.repo_nix_store_path }}
run: |
set -exu
if [[ -d "${HOLOCHAIN_REPO}" ]]; then
echo repository at ${HOLOCHAIN_REPO} unexpectedly exists
exit 1
fi
# this fetches the repo from the nix cache
nix-store --realise ${HOLOCHAIN_REPO_NIX_STORE_PATH}
mkdir -p $(dirname ${HOLOCHAIN_REPO})
cp -rv --no-preserve=ownership ${HOLOCHAIN_REPO_NIX_STORE_PATH} ${HOLOCHAIN_REPO}
chmod --recursive u+w ${HOLOCHAIN_REPO}
cp -v $HOME/work/holochain/holochain/.git/config ${HOLOCHAIN_REPO}/.git/config
- name: Restore cargo related state and build files
uses: steveeJ-forks/actions-cache/restore@retry
with:
path: |
/var/tmp/holochain_repo/.cargo/bin/
/var/tmp/holochain_repo/.cargo/registry/index/
/var/tmp/holochain_repo/.cargo/registry/cache/
/var/tmp/holochain_repo/.cargo/git/db/
/var/tmp/holochain_repo/target/
key: ${{ runner.os }}-prepare-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-test-
${{ runner.os }}-prepare-
required: false
- name: Ensure the git credentials are set
env:
HRA_GITHUB_TOKEN: ${{ secrets.HRA_GITHUB_TOKEN }}
run: |
set -xeu
cd "${HOLOCHAIN_REPO}"
# regenerate the nix sources
git config --global user.email "[email protected]"
git config --global user.name "Holochain Core Dev Team"
# use our custom token for more permissions, e.g. "workflow" which is needed to push workflow files
git config --local "http.https://github.com/.extraheader" "AUTHORIZATION: basic $(echo -n pat:${HRA_GITHUB_TOKEN} | base64)"
- name: Merge release branch (${{ needs.prepare.outputs.release_branch }}) into target branch (${{ needs.vars.outputs.holochain_target_branch }}) and push it
env:
RELEASE_BRANCH: ${{ needs.prepare.outputs.release_branch }}
HOLOCHAIN_TARGET_BRANCH: ${{ needs.vars.outputs.holochain_target_branch }}
DRY_RUN: "${{ needs.vars.outputs.dry_run }}"
run: |
set -xeu
cd "${HOLOCHAIN_REPO}"
git status
git checkout ${HOLOCHAIN_TARGET_BRANCH}
git merge --ff-only ${RELEASE_BRANCH}
if [[ "${DRY_RUN}" == "false" ]]; then
git push origin ${HOLOCHAIN_TARGET_BRANCH}
fi
- name: Push the release branch
id: push-release-branch
env:
RELEASE_BRANCH: ${{ needs.prepare.outputs.release_branch }}
HOLOCHAIN_REPO_NIX_STORE_PATH: ${{ needs.prepare.outputs.repo_nix_store_path }}
run: |
set -xeu
cd "${HOLOCHAIN_REPO}"
git checkout ${RELEASE_BRANCH}
git push origin ${RELEASE_BRANCH}
- name: Publish crates
if: ${{ needs.vars.outputs.dry_run == 'false' }}
id: publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
cd "${HOLOCHAIN_REPO}"
nix develop .#release \
--ignore-environment \
--keep CARGO_REGISTRY_TOKEN \
--command release-automation \
--workspace-path=$PWD \
--log-level=trace \
release \
--no-verify \
--steps=PublishToCratesIo,AddOwnersToCratesIo
- name: Push the tags
if: ${{ needs.vars.outputs.dry_run == 'false' }}
id: push-tags
env:
HOLOCHAIN_TARGET_BRANCH: ${{ needs.vars.outputs.holochain_target_branch }}
run: |
set -eu
cd "${HOLOCHAIN_REPO}"
git status
git push origin ${HOLOCHAIN_TARGET_BRANCH} --tags
- name: Merge release branch into source branch
continue-on-error: true
id: merge-into-source
env:
RELEASE_BRANCH: ${{ needs.prepare.outputs.release_branch }}
HOLOCHAIN_SOURCE_BRANCH: ${{ needs.vars.outputs.holochain_source_branch }}
run: |
set -xeu
cd "${HOLOCHAIN_REPO}"
git fetch origin ${HOLOCHAIN_SOURCE_BRANCH}
git checkout -B ${HOLOCHAIN_SOURCE_BRANCH} origin/${HOLOCHAIN_SOURCE_BRANCH}
git merge ${RELEASE_BRANCH}
- name: Push the updated source branch
if: ${{ needs.vars.outputs.dry_run == 'false' }}
continue-on-error: true
env:
HOLOCHAIN_SOURCE_BRANCH: ${{ needs.vars.outputs.holochain_source_branch }}
run: |
set -xeu
cd "${HOLOCHAIN_REPO}"
git status
git pull origin ${HOLOCHAIN_SOURCE_BRANCH}
git push origin ${HOLOCHAIN_SOURCE_BRANCH}
- name: Create a pull-request towards the source branch
id: cpr
if: ${{ always() && steps.push-release-branch.outcome == 'success' && (needs.vars.outputs.dry_run == 'true' || (steps.publish.outcome == 'failed' || steps.push-tags.outcome == 'failed' || steps.merge-into-source.outcome == 'failed')) }}
continue-on-error: ${{ needs.prepare.outputs.releasable_crates != 'true' }}
env:
RELEASE_BRANCH: ${{ needs.prepare.outputs.release_branch }}
HOLOCHAIN_SOURCE_BRANCH: ${{ needs.vars.outputs.holochain_source_branch }}
GITHUB_TOKEN: ${{ secrets.HRA_GITHUB_TOKEN }}
run: |
set -xeuE -o pipefail
cd "${HOLOCHAIN_REPO}"
gh pr create \
--title "Merge ${RELEASE_BRANCH} back into ${HOLOCHAIN_SOURCE_BRANCH}" \
--label release \
--label "autoupdate:opt-in" \
--base ${HOLOCHAIN_SOURCE_BRANCH} --head "${RELEASE_BRANCH}" \
--body 'Please double-check the consistency of the CHANGELOG.md files' 2>&1 | tee gh-pr-create.log
# --reviewer "holochain/core-dev" \
pull_request_number="$(tail -n1 gh-pr-create.log | grep -oE '[0-9]+$')"
echo "pull-request-number=${pull_request_number}" >> $GITHUB_OUTPUT
- name: Create a github release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOLOCHAIN_TARGET_BRANCH: ${{ needs.vars.outputs.holochain_target_branch }}
RELEASE_BRANCH: ${{ needs.prepare.outputs.release_branch }}
LATEST_HOLOCHAIN_TAG: ${{ needs.prepare.outputs.latest_holochain_tag }}
LATEST_HOLOCHAIN_VERSION: ${{ needs.prepare.outputs.latest_holochain_version }}
DRY_RUN: "${{ needs.vars.outputs.dry_run }}"
run: |
set -eux
cd "${GITHUB_WORKSPACE}"
./scripts/ci-gh-release.sh
- name: Setup SSH session
uses: steveeJ-forks/action-upterm@main
if: ${{ failure() && needs.vars.outputs.debug == 'true' }}
env:
GITHUB_ACTION_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_HRA_ACTION_TOKEN: ${{ secrets.HRA_GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
with:
## limits ssh access and adds the ssh public key for the user which triggered the workflow
limit-access-to-actor: true
## limits ssh access and adds the ssh public keys of the listed GitHub users
limit-access-to-users: steveeJ,jost-s,freesig,neonphog,thedavidmeister,maackle
github-actions-ci-jobs-succeed:
if: ${{ always() && github.event_name == 'pull_request' }}
runs-on: "ubuntu-latest"
needs: [vars, test, prepare]
steps:
- name: Check status
id: check-status
env:
RESULTS: "${{ toJSON(needs.*.result) }}"
DRY_RUN: "${{ needs.vars.outputs.dry_run }}"
SKIP_TEST: "${{ needs.vars.outputs.skip_test }}"
run: |
[[ $(jq -n 'env.RESULTS | fromjson | unique == ["success"]') == 'true' ]] || \
[[ (${DRY_RUN} == 'true' || ${SKIP_TEST} == 'true') && $(jq -n 'env.RESULTS | fromjson | unique | sort == ["skipped", "success"]') == 'true' ]]
- name: Post mattermost message
if: always()
shell: bash
continue-on-error: true
env:
STATUS: ${{ steps.check-status.outcome }}
VERSION: ${{ needs.prepare.outputs.latest_holochain_version }}
TAG: ${{ needs.prepare.outputs.latest_holochain_tag }}
WORKFLOW_RUN_URL: "https://github.com/holochain/holochain/actions/runs/${{ github.run_id }}"
HRA_MATTERMOST_TOKEN: ${{ secrets.HRA_MATTERMOST_TOKEN }}
# dev/holochain-rsm/CI
MM_CHANNEL_ID: "uzjosy5d3fdcxe35oyw9naihfw"
run: |
set -xeEu
if [[ "${STATUS}" == "success" ]]; then
holochain_status=":white_check_mark:"
else
holochain_status=":x:"
fi
holochain_status="${holochain_status} [log](${WORKFLOW_RUN_URL})"
message=$(cat <<-EOF
#### Holochain release run (ci-mode)
Version | ${VERSION}
--- | ---
holochain | ${holochain_status}
EOF
)
export message
data=$(jq -n --compact-output '{"channel_id":env.MM_CHANNEL_ID, "message":env.message, "props":{"version":env.VERSION}}')
curl -X POST -H "Authorization: Bearer ${HRA_MATTERMOST_TOKEN}" -d "$data" https://chat.holochain.org/api/v4/posts
- name: Trigger status event
if: always()
shell: bash
continue-on-error: true
env:
STATUS: ${{ steps.check-status.outcome }}
WORKFLOW_RUN_URL: "https://github.com/holochain/holochain/actions/runs/${{ github.run_id }}"
run: |
set -x
data=$(jq -n --compact-output '{
"state":env.STATUS,
"target_url":env.WORKFLOW_RUN_URL,
"description":"release workflow completed",
"context":"github-actions/relelase-holochain"
}')
curl -L -X POST \
-H "Content-Type: application/json" \
-H "Authorization: token ${{ secrets.HRA_GITHUB_TOKEN}}" \
-d "$data" \
"https://api.github.com/repos/${GITHUB_REPOSITORY}/statuses/${{ github.sha }}"
all-jobs-succeed:
if: ${{ always() && github.event_name != 'pull_request' }}
runs-on: "ubuntu-latest"
needs: [vars, prepare, test, finalize]
steps:
- name: Check status
id: check-status
env:
RESULTS: "${{ toJSON(needs.*.result) }}"
DRY_RUN: "${{ needs.vars.outputs.dry_run }}"
SKIP_TEST: "${{ needs.vars.outputs.skip_test }}"
run: |
[[ $(jq -n 'env.RESULTS | fromjson | unique == ["success"]') == 'true' ]] || \
[[ (${DRY_RUN} == 'true' || ${SKIP_TEST} == 'true') && $(jq -n 'env.RESULTS | fromjson | unique | sort == ["skipped", "success"]') == 'true' ]]
- name: Post mattermost message
if: always()
continue-on-error: true
env:
STATUS: ${{ steps.check-status.outcome }}
VERSION: ${{ needs.prepare.outputs.latest_holochain_version }}
TAG: ${{ needs.prepare.outputs.latest_holochain_tag }}
WORKFLOW_RUN_URL: "https://github.com/holochain/holochain/actions/runs/${{ github.run_id }}"
HRA_MATTERMOST_TOKEN: ${{ secrets.HRA_MATTERMOST_TOKEN }}
DRY_RUN: "${{ needs.vars.outputs.dry_run }}"
RELEASABLE_CRATES: ${{ needs.prepare.outputs.releasable_crates }}
# dev/HC-releases
MM_CHANNEL_ID: "cdxeytdc97ff3e1jbdzgyfcduo"
run: |
if [[ "${STATUS}" == "success" ]]; then
# TODO: adapt tag to case where holochain isn't released
holochain_status="success :white_check_mark: [log](${WORKFLOW_RUN_URL}), [tag](https://github.com/holochain/holochain/releases/tag/${TAG})"
elif [[ "${RELEASABLE_CRATES}" == "false" ]]; then
holochain_status="no changes to release :ballot_box_with_check: [log](${WORKFLOW_RUN_URL})"
else
holochain_status="failure :x: [log](${WORKFLOW_RUN_URL})"
fi
mode="release-mode"
if [[ "${DRY_RUN}" == "true" ]]; then
mode="${mode}, dry-run"
fi
message=$(cat <<-EOF
#### Holochain release run (${mode})
Version | ${VERSION}
--- | ---
holochain | ${holochain_status}
holonix | _undetermined_
EOF
)
export message
data=$(jq -n --compact-output '{"channel_id":env.MM_CHANNEL_ID, "message":env.message, "props":{"version":env.VERSION}}')
curl -X POST -H "Authorization: Bearer ${HRA_MATTERMOST_TOKEN}" -d "$data" https://chat.holochain.org/api/v4/posts