diff --git a/.gitea/workflows/poll-upstream.yml b/.gitea/workflows/poll-upstream.yml index ca2b79c..42ec01a 100644 --- a/.gitea/workflows/poll-upstream.yml +++ b/.gitea/workflows/poll-upstream.yml @@ -1,155 +1 @@ -name: poll-upstream - -on: - schedule: - - cron: "0 * * * *" - workflow_dispatch: {} - -concurrency: - group: poll-upstream - cancel-in-progress: true - -jobs: - check: - runs-on: fedora-43 - steps: - - name: Get upstream latest tag - id: upstream - run: | - tag=$(curl -sSfL \ - -H 'Accept: application/vnd.github+json' \ - https://api.github.com/repos/EricLBuehler/mistral.rs/releases/latest \ - | jq -r .tag_name) - echo "tag=${tag}" >> "$GITHUB_OUTPUT" - echo "Upstream latest: ${tag}" - - - name: Check if all packages are published - id: published - run: | - version="${UPSTREAM_TAG#v}" - needs_build=false - for target in "43:ampere" "43:ada" "43:blackwell"; do - fedora_version="${target%%:*}" - flavour="${target##*:}" - base_url="https://rpm.lair.cafe/fedora/${fedora_version}/x86_64" - rpm_name="mistralrs-${flavour}-${version}-1.fc${fedora_version}.x86_64.rpm" - - # check that the rpm file exists - http_code=$(curl \ - --silent \ - --write-out "%{http_code}" \ - --output /dev/null \ - --head \ - --url "${base_url}/${rpm_name}") - if [ "${http_code}" = "404" ]; then - echo "missing: ${base_url}/${rpm_name}" - needs_build=true - continue - elif [ "${http_code}" != "200" ]; then - echo "unexpected HTTP ${http_code} for ${base_url}/${rpm_name}" - exit 1 - fi - echo "found: ${base_url}/${rpm_name}" - - # check that the repo index references this package - if ! curl --silent --fail "${base_url}/repodata/repomd.xml" \ - | grep --quiet 'primary'; then - echo "missing or invalid repomd.xml at ${base_url}/repodata/" - needs_build=true - continue - fi - if ! dnf repoquery \ - --repofrompath=check,"${base_url}" \ - --repo=check \ - --quiet \ - "mistralrs-${flavour}-${version}" 2>&1 \ - | grep --quiet "mistralrs-${flavour}"; then - echo "repo index missing: mistralrs-${flavour}-${version} not in ${base_url}/repodata/" - needs_build=true - continue - fi - echo "indexed: mistralrs-${flavour}-${version} in ${base_url}/repodata/" - done - echo "already_built=$( [ "${needs_build}" = "true" ] && echo false || echo true )" >> "$GITHUB_OUTPUT" - env: - UPSTREAM_TAG: ${{ steps.upstream.outputs.tag }} - - - name: Trigger build workflow - if: steps.published.outputs.already_built == 'false' - run: | - curl --fail --silent --show-error --location \ - --request POST \ - --header "Authorization: token ${{ secrets.DISPATCH_TOKEN }}" \ - --header 'Content-Type: application/json' \ - --url "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/actions/workflows/build-release.yml/dispatches" \ - --data "{\"ref\":\"refs/heads/main\",\"inputs\":{\"tag\":\"${{ steps.upstream.outputs.tag }}\"}}" - - check-prerelease: - runs-on: fedora-43 - steps: - - name: Get upstream main branch HEAD - id: upstream - run: | - response=$(curl --silent --show-error --fail --location \ - --header 'Accept: application/vnd.github+json' \ - --url 'https://api.github.com/repos/EricLBuehler/mistral.rs/commits/master') - sha=$(echo "${response}" | jq -r .sha) - short_sha=$(echo "${sha}" | head --bytes=7) - date=$(echo "${response}" | jq -r '.commit.committer.date[:10]' | tr -d '-') - echo "sha=${sha}" >> "$GITHUB_OUTPUT" - echo "short_sha=${short_sha}" >> "$GITHUB_OUTPUT" - echo "date=${date}" >> "$GITHUB_OUTPUT" - echo "Upstream main HEAD: ${sha} (${date})" - - - name: Get version from upstream Cargo.toml - id: version - run: | - version=$(curl --silent --show-error --fail --location \ - --header 'Accept: application/vnd.github.raw+json' \ - --url "https://api.github.com/repos/EricLBuehler/mistral.rs/contents/Cargo.toml?ref=${{ steps.upstream.outputs.sha }}" \ - | grep '^version' | head --lines=1 | sed 's/.*"\(.*\)".*/\1/') - echo "version=${version}" >> "$GITHUB_OUTPUT" - echo "Upstream Cargo.toml version: ${version}" - - - name: Check if prerelease is already published - id: published - run: | - prerelease="0.1.${UPSTREAM_DATE}git${UPSTREAM_SHORT_SHA}" - needs_build=false - for target in "43:ampere" "43:ada" "43:blackwell"; do - fedora_version="${target%%:*}" - flavour="${target##*:}" - base_url="https://rpm.lair.cafe/fedora/${fedora_version}/x86_64/unstable" - rpm_name="mistralrs-${flavour}-${UPSTREAM_VERSION}-${prerelease}.fc${fedora_version}.x86_64.rpm" - - http_code=$(curl \ - --silent \ - --write-out "%{http_code}" \ - --output /dev/null \ - --head \ - --url "${base_url}/${rpm_name}") - if [ "${http_code}" = "404" ]; then - echo "missing: ${base_url}/${rpm_name}" - needs_build=true - continue - elif [ "${http_code}" != "200" ]; then - echo "unexpected HTTP ${http_code} for ${base_url}/${rpm_name}" - exit 1 - fi - echo "found: ${base_url}/${rpm_name}" - done - echo "already_built=$( [ "${needs_build}" = "true" ] && echo false || echo true )" >> "$GITHUB_OUTPUT" - env: - UPSTREAM_VERSION: ${{ steps.version.outputs.version }} - UPSTREAM_DATE: ${{ steps.upstream.outputs.date }} - UPSTREAM_SHORT_SHA: ${{ steps.upstream.outputs.short_sha }} - - - name: Trigger prerelease build workflow - if: steps.published.outputs.already_built == 'false' - run: | - curl --fail --silent --show-error --location \ - --request POST \ - --header "Authorization: token ${{ secrets.DISPATCH_TOKEN }}" \ - --header 'Content-Type: application/json' \ - --url "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/actions/workflows/build-prerelease.yml/dispatches" \ - --data "{\"ref\":\"refs/heads/main\",\"inputs\":{\"commit\":\"${{ steps.upstream.outputs.sha }}\",\"version\":\"${{ steps.version.outputs.version }}\",\"date\":\"${{ steps.upstream.outputs.date }}\",\"short_sha\":\"${{ steps.upstream.outputs.short_sha }}\"}}" +bmFtZTogcG9sbC11cHN0cmVhbQoKb246CiAgc2NoZWR1bGU6CiAgICAtIGNyb246ICIwICovNiAqICogKiIKICB3b3JrZmxvd19kaXNwYXRjaDoge30KCmNvbmN1cnJlbmN5OgogIGdyb3VwOiBwb2xsLXVwc3RyZWFtCiAgY2FuY2VsLWluLXByb2dyZXNzOiB0cnVlCgpqb2JzOgogIGNoZWNrOgogICAgcnVucy1vbjogZmVkb3JhLTQzCiAgICBzdGVwczoKICAgICAgLSBuYW1lOiBHZXQgdXBzdHJlYW0gbGF0ZXN0IHRhZwogICAgICAgIGlkOiB1cHN0cmVhbQogICAgICAgIHJ1bjogfAogICAgICAgICAgdGFnPSQoY3VybCAtc1NmTCBcCiAgICAgICAgICAgIC1IICdBY2NlcHQ6IGFwcGxpY2F0aW9uL3ZuZC5naXRodWIranNvbicgXAogICAgICAgICAgICBodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL0VyaWNMQnVlaGxlci9taXN0cmFsLnJzL3JlbGVhc2VzL2xhdGVzdCBcCiAgICAgICAgICAgIHwganEgLXIgLnRhZ19uYW1lKQogICAgICAgICAgZWNobyAidGFnPSR7dGFnfSIgPj4gIiRHSVRIVUJfT1VUUFVUIgogICAgICAgICAgZWNobyAiVXBzdHJlYW0gbGF0ZXN0OiAke3RhZ30iCgogICAgICAtIG5hbWU6IENoZWNrIGlmIGFsbCBwYWNrYWdlcyBhcmUgcHVibGlzaGVkCiAgICAgICAgaWQ6IHB1Ymxpc2hlZAogICAgICAgIHJ1bjogfAogICAgICAgICAgdmVyc2lvbj0iJHtVUFNUUkVBTV9UQUcjdn0iCiAgICAgICAgICBuZWVkc19idWlsZD1mYWxzZQogICAgICAgICAgZm9yIHRhcmdldCBpbiAiNDM6YW1wZXJlIiAiNDM6YWRhIiAiNDM6YmxhY2t3ZWxsIjsgZG8KICAgICAgICAgICAgZmVkb3JhX3ZlcnNpb249IiR7dGFyZ2V0JSU6Kn0iCiAgICAgICAgICAgIGZsYXZvdXI9IiR7dGFyZ2V0IyMqOn0iCiAgICAgICAgICAgIGJhc2VfdXJsPSJodHRwczovL3JwbS5sYWlyLmNhZmUvZmVkb3JhLyR7ZmVkb3JhX3ZlcnNpb259L3g4Nl82NCIKICAgICAgICAgICAgcnBtX25hbWU9Im1pc3RyYWxycy0ke2ZsYXZvdXJ9LSR7dmVyc2lvbn0tMS5mYyR7ZmVkb3JhX3ZlcnNpb259Lng4Nl82NC5ycG0iCgogICAgICAgICAgICAjIGNoZWNrIHRoYXQgdGhlIHJwbSBmaWxlIGV4aXN0cwogICAgICAgICAgICBodHRwX2NvZGU9JChjdXJsIFwKICAgICAgICAgICAgICAgIC0tc2lsZW50IFwKICAgICAgICAgICAgICAgIC0td3JpdGUtb3V0ICIle2h0dHBfY29kZX0iIFwKICAgICAgICAgICAgICAgIC0tb3V0cHV0IC9kZXYvbnVsbCBcCiAgICAgICAgICAgICAgICAtLWhlYWQgXAogICAgICAgICAgICAgICAgLS11cmwgIiR7YmFzZV91cmx9LyR7cnBtX25hbWV9IikKICAgICAgICAgICAgaWYgWyAiJHtodHRwX2NvZGV9IiA9ICI0MDQiIF07IHRoZW4KICAgICAgICAgICAgICBlY2hvICJtaXNzaW5nOiAke2Jhc2VfdXJsfS8ke3JwbV9uYW1lfSIKICAgICAgICAgICAgICBuZWVkc19idWlsZD10cnVlCiAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZWxpZiBbICIke2h0dHBfY29kZX0iICE9ICIyMDAiIF07IHRoZW4KICAgICAgICAgICAgICBlY2hvICJ1bmV4cGVjdGVkIEhUVFAgJHtodHRwX2NvZGV9IGZvciAke2Jhc2VfdXJsfS8ke3JwbV9uYW1lfSIKICAgICAgICAgICAgICBleGl0IDEKICAgICAgICAgICAgZmkKICAgICAgICAgICAgZWNobyAiZm91bmQ6ICR7YmFzZV91cmx9LyR7cnBtX25hbWV9IgoKICAgICAgICAgICAgIyBjaGVjayB0aGF0IHRoZSByZXBvIGluZGV4IHJlZmVyZW5jZXMgdGhpcyBwYWNrYWdlCiAgICAgICAgICAgIGlmICEgY3VybCAtLXNpbGVudCAtLWZhaWwgIiR7YmFzZV91cmx9L3JlcG9kYXRhL3JlcG9tZC54bWwiIFwKICAgICAgICAgICAgICAgIHwgZ3JlcCAtLXF1aWV0ICdwcmltYXJ5JzsgdGhlbgogICAgICAgICAgICAgIGVjaG8gIm1pc3Npbmcgb3IgaW52YWxpZCByZXBvbWQueG1sIGF0ICR7YmFzZV91cmx9L3JlcG9kYXRhLyIKICAgICAgICAgICAgICBuZWVkc19idWlsZD10cnVlCiAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgZmkKICAgICAgICAgICAgaWYgISBkbmYgcmVwb3F1ZXJ5IFwKICAgICAgICAgICAgICAgIC0tcmVwb2Zyb21wYXRoPWNoZWNrLCIke2Jhc2VfdXJsfSIgXAogICAgICAgICAgICAgICAgLS1yZXBvPWNoZWNrIFwKICAgICAgICAgICAgICAgIC0tcXVpZXQgXAogICAgICAgICAgICAgICAgIm1pc3RyYWxycy0ke2ZsYXZvdXJ9LSR7dmVyc2lvbn0iIDI+JjEgXAogICAgICAgICAgICAgICAgfCBncmVwIC0tcXVpZXQgIm1pc3RyYWxycy0ke2ZsYXZvdXJ9IjsgdGhlbgogICAgICAgICAgICAgIGVjaG8gInJlcG8gaW5kZXggbWlzc2luZzogbWlzdHJhbHJzLSR7Zmxhdm91cn0tJHt2ZXJzaW9ufSBub3QgaW4gJHtiYXNlX3VybH0vcmVwb2RhdGEvIgogICAgICAgICAgICAgIG5lZWRzX2J1aWxkPXRydWUKICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICBmaQogICAgICAgICAgICBlY2hvICJpbmRleGVkOiBtaXN0cmFscnMtJHtmbGF2b3VyfS0ke3ZlcnNpb259IGluICR7YmFzZV91cmx9L3JlcG9kYXRhLyIKICAgICAgICAgIGRvbmUKICAgICAgICAgIGVjaG8gImFscmVhZHlfYnVpbHQ9JCggWyAiJHtuZWVkc19idWlsZH0iID0gInRydWUiIF0gJiYgZWNobyBmYWxzZSB8fCBlY2hvIHRydWUgKSIgPj4gIiRHSVRIVUJfT1VUUFVUIgogICAgICAgIGVudjoKICAgICAgICAgIFVQU1RSRUFNX1RBRzogJHt7IHN0ZXBzLnVwc3RyZWFtLm91dHB1dHMudGFnIH19CgogICAgICAjIEluLWZsaWdodCBndWFyZDogYSBkaXNwYXRjaCB3aGlsZSBhIGJ1aWxkLXJlbGVhc2UgcnVuIGlzIHF1ZXVlZCBvcgogICAgICAjIGV4ZWN1dGluZyB3b3VsZCBjYW5jZWwgaXQgKGNvbmN1cnJlbmN5IGNhbmNlbC1pbi1wcm9ncmVzcykgYW5kIHJlc3RhcnQKICAgICAgIyBpZGVudGljYWwgd29yayDigJQgYnVpbGRzIGxvbmdlciB0aGFuIHRoZSBwb2xsIGludGVydmFsIGNvdWxkIG5ldmVyCiAgICAgICMgZmluaXNoLiBTa2lwIGRpc3BhdGNoaW5nIGFuZCBsZXQgdGhlIHJ1bm5pbmcgYnVpbGQgY29tcGxldGU7IHRoZSBuZXh0CiAgICAgICMgcG9sbCByZS1jaGVja3MgdGhlIHB1Ymxpc2hlZCBSUE1zLgogICAgICAtIG5hbWU6IENoZWNrIGZvciBpbi1mbGlnaHQgcmVsZWFzZSBidWlsZAogICAgICAgIGlkOiBpbmZsaWdodAogICAgICAgIHJ1bjogfAogICAgICAgICAgY291bnQ9JChjdXJsIC0tZmFpbCAtLXNpbGVudCAtLXNob3ctZXJyb3IgLS1sb2NhdGlvbiBcCiAgICAgICAgICAgIC0taGVhZGVyICJBdXRob3JpemF0aW9uOiB0b2tlbiAke3sgc2VjcmV0cy5ESVNQQVRDSF9UT0tFTiB9fSIgXAogICAgICAgICAgICAtLXVybCAiJHt7IGdpdGh1Yi5zZXJ2ZXJfdXJsIH19L2FwaS92MS9yZXBvcy8ke3sgZ2l0aHViLnJlcG9zaXRvcnkgfX0vYWN0aW9ucy9ydW5zP2xpbWl0PTUwIiBcCiAgICAgICAgICAgIHwganEgJ1sud29ya2Zsb3dfcnVuc1tdCiAgICAgICAgICAgICAgICAgICB8IHNlbGVjdCgucGF0aCB8IGVuZHN3aXRoKCJidWlsZC1yZWxlYXNlLnltbCIpKQogICAgICAgICAgICAgICAgICAgfCBzZWxlY3QoLnN0YXR1cyAhPSAiY29tcGxldGVkIildIHwgbGVuZ3RoJykKICAgICAgICAgIGVjaG8gImNvdW50PSR7Y291bnR9IiA+PiAiJEdJVEhVQl9PVVRQVVQiCiAgICAgICAgICBlY2hvICJpbi1mbGlnaHQgYnVpbGQtcmVsZWFzZSBydW5zOiAke2NvdW50fSIKCiAgICAgIC0gbmFtZTogVHJpZ2dlciBidWlsZCB3b3JrZmxvdwogICAgICAgIGlmOiBzdGVwcy5wdWJsaXNoZWQub3V0cHV0cy5hbHJlYWR5X2J1aWx0ID09ICdmYWxzZScgJiYgc3RlcHMuaW5mbGlnaHQub3V0cHV0cy5jb3VudCA9PSAnMCcKICAgICAgICBydW46IHwKICAgICAgICAgIGN1cmwgLS1mYWlsIC0tc2lsZW50IC0tc2hvdy1lcnJvciAtLWxvY2F0aW9uIFwKICAgICAgICAgICAgLS1yZXF1ZXN0IFBPU1QgXAogICAgICAgICAgICAtLWhlYWRlciAiQXV0aG9yaXphdGlvbjogdG9rZW4gJHt7IHNlY3JldHMuRElTUEFUQ0hfVE9LRU4gfX0iIFwKICAgICAgICAgICAgLS1oZWFkZXIgJ0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbicgXAogICAgICAgICAgICAtLXVybCAiJHt7IGdpdGh1Yi5zZXJ2ZXJfdXJsIH19L2FwaS92MS9yZXBvcy8ke3sgZ2l0aHViLnJlcG9zaXRvcnkgfX0vYWN0aW9ucy93b3JrZmxvd3MvYnVpbGQtcmVsZWFzZS55bWwvZGlzcGF0Y2hlcyIgXAogICAgICAgICAgICAtLWRhdGEgIntcInJlZlwiOlwicmVmcy9oZWFkcy9tYWluXCIsXCJpbnB1dHNcIjp7XCJ0YWdcIjpcIiR7eyBzdGVwcy51cHN0cmVhbS5vdXRwdXRzLnRhZyB9fVwifX0iCgogIGNoZWNrLXByZXJlbGVhc2U6CiAgICBydW5zLW9uOiBmZWRvcmEtNDMKICAgIHN0ZXBzOgogICAgICAtIG5hbWU6IEdldCB1cHN0cmVhbSBtYWluIGJyYW5jaCBIRUFECiAgICAgICAgaWQ6IHVwc3RyZWFtCiAgICAgICAgcnVuOiB8CiAgICAgICAgICByZXNwb25zZT0kKGN1cmwgLS1zaWxlbnQgLS1zaG93LWVycm9yIC0tZmFpbCAtLWxvY2F0aW9uIFwKICAgICAgICAgICAgLS1oZWFkZXIgJ0FjY2VwdDogYXBwbGljYXRpb24vdm5kLmdpdGh1Yitqc29uJyBcCiAgICAgICAgICAgIC0tdXJsICdodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL0VyaWNMQnVlaGxlci9taXN0cmFsLnJzL2NvbW1pdHMvbWFzdGVyJykKICAgICAgICAgIHNoYT0kKGVjaG8gIiR7cmVzcG9uc2V9IiB8IGpxIC1yIC5zaGEpCiAgICAgICAgICBzaG9ydF9zaGE9JChlY2hvICIke3NoYX0iIHwgaGVhZCAtLWJ5dGVzPTcpCiAgICAgICAgICBkYXRlPSQoZWNobyAiJHtyZXNwb25zZX0iIHwganEgLXIgJy5jb21taXQuY29tbWl0dGVyLmRhdGVbOjEwXScgfCB0ciAtZCAnLScpCiAgICAgICAgICBlY2hvICJzaGE9JHtzaGF9IiA+PiAiJEdJVEhVQl9PVVRQVVQiCiAgICAgICAgICBlY2hvICJzaG9ydF9zaGE9JHtzaG9ydF9zaGF9IiA+PiAiJEdJVEhVQl9PVVRQVVQiCiAgICAgICAgICBlY2hvICJkYXRlPSR7ZGF0ZX0iID4+ICIkR0lUSFVCX09VVFBVVCIKICAgICAgICAgIGVjaG8gIlVwc3RyZWFtIG1haW4gSEVBRDogJHtzaGF9ICgke2RhdGV9KSIKCiAgICAgIC0gbmFtZTogR2V0IHZlcnNpb24gZnJvbSB1cHN0cmVhbSBDYXJnby50b21sCiAgICAgICAgaWQ6IHZlcnNpb24KICAgICAgICBydW46IHwKICAgICAgICAgIHZlcnNpb249JChjdXJsIC0tc2lsZW50IC0tc2hvdy1lcnJvciAtLWZhaWwgLS1sb2NhdGlvbiBcCiAgICAgICAgICAgIC0taGVhZGVyICdBY2NlcHQ6IGFwcGxpY2F0aW9uL3ZuZC5naXRodWIucmF3K2pzb24nIFwKICAgICAgICAgICAgLS11cmwgImh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vcmVwb3MvRXJpY0xCdWVobGVyL21pc3RyYWwucnMvY29udGVudHMvQ2FyZ28udG9tbD9yZWY9JHt7IHN0ZXBzLnVwc3RyZWFtLm91dHB1dHMuc2hhIH19IiBcCiAgICAgICAgICAgIHwgZ3JlcCAnXnZlcnNpb24nIHwgaGVhZCAtLWxpbmVzPTEgfCBzZWQgJ3MvLioiXCguKlwpIi4qL1wxLycpCiAgICAgICAgICBlY2hvICJ2ZXJzaW9uPSR7dmVyc2lvbn0iID4+ICIkR0lUSFVCX09VVFBVVCIKICAgICAgICAgIGVjaG8gIlVwc3RyZWFtIENhcmdvLnRvbWwgdmVyc2lvbjogJHt2ZXJzaW9ufSIKCiAgICAgIC0gbmFtZTogQ2hlY2sgaWYgcHJlcmVsZWFzZSBpcyBhbHJlYWR5IHB1Ymxpc2hlZAogICAgICAgIGlkOiBwdWJsaXNoZWQKICAgICAgICBydW46IHwKICAgICAgICAgIHByZXJlbGVhc2U9IjAuMS4ke1VQU1RSRUFNX0RBVEV9Z2l0JHtVUFNUUkVBTV9TSE9SVF9TSEF9IgogICAgICAgICAgbmVlZHNfYnVpbGQ9ZmFsc2UKICAgICAgICAgIGZvciB0YXJnZXQgaW4gIjQzOmFtcGVyZSIgIjQzOmFkYSIgIjQzOmJsYWNrd2VsbCI7IGRvCiAgICAgICAgICAgIGZlZG9yYV92ZXJzaW9uPSIke3RhcmdldCUlOip9IgogICAgICAgICAgICBmbGF2b3VyPSIke3RhcmdldCMjKjp9IgogICAgICAgICAgICBiYXNlX3VybD0iaHR0cHM6Ly9ycG0ubGFpci5jYWZlL2ZlZG9yYS8ke2ZlZG9yYV92ZXJzaW9ufS94ODZfNjQvdW5zdGFibGUiCiAgICAgICAgICAgIHJwbV9uYW1lPSJtaXN0cmFscnMtJHtmbGF2b3VyfS0ke1VQU1RSRUFNX1ZFUlNJT059LSR7cHJlcmVsZWFzZX0uZmMke2ZlZG9yYV92ZXJzaW9ufS54ODZfNjQucnBtIgoKICAgICAgICAgICAgaHR0cF9jb2RlPSQoY3VybCBcCiAgICAgICAgICAgICAgICAtLXNpbGVudCBcCiAgICAgICAgICAgICAgICAtLXdyaXRlLW91dCAiJXtodHRwX2NvZGV9IiBcCiAgICAgICAgICAgICAgICAtLW91dHB1dCAvZGV2L251bGwgXAogICAgICAgICAgICAgICAgLS1oZWFkIFwKICAgICAgICAgICAgICAgIC0tdXJsICIke2Jhc2VfdXJsfS8ke3JwbV9uYW1lfSIpCiAgICAgICAgICAgIGlmIFsgIiR7aHR0cF9jb2RlfSIgPSAiNDA0IiBdOyB0aGVuCiAgICAgICAgICAgICAgZWNobyAibWlzc2luZzogJHtiYXNlX3VybH0vJHtycG1fbmFtZX0iCiAgICAgICAgICAgICAgbmVlZHNfYnVpbGQ9dHJ1ZQogICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGVsaWYgWyAiJHtodHRwX2NvZGV9IiAhPSAiMjAwIiBdOyB0aGVuCiAgICAgICAgICAgICAgZWNobyAidW5leHBlY3RlZCBIVFRQICR7aHR0cF9jb2RlfSBmb3IgJHtiYXNlX3VybH0vJHtycG1fbmFtZX0iCiAgICAgICAgICAgICAgZXhpdCAxCiAgICAgICAgICAgIGZpCiAgICAgICAgICAgIGVjaG8gImZvdW5kOiAke2Jhc2VfdXJsfS8ke3JwbV9uYW1lfSIKICAgICAgICAgIGRvbmUKICAgICAgICAgIGVjaG8gImFscmVhZHlfYnVpbHQ9JCggWyAiJHtuZWVkc19idWlsZH0iID0gInRydWUiIF0gJiYgZWNobyBmYWxzZSB8fCBlY2hvIHRydWUgKSIgPj4gIiRHSVRIVUJfT1VUUFVUIgogICAgICAgIGVudjoKICAgICAgICAgIFVQU1RSRUFNX1ZFUlNJT046ICR7eyBzdGVwcy52ZXJzaW9uLm91dHB1dHMudmVyc2lvbiB9fQogICAgICAgICAgVVBTVFJFQU1fREFURTogJHt7IHN0ZXBzLnVwc3RyZWFtLm91dHB1dHMuZGF0ZSB9fQogICAgICAgICAgVVBTVFJFQU1fU0hPUlRfU0hBOiAke3sgc3RlcHMudXBzdHJlYW0ub3V0cHV0cy5zaG9ydF9zaGEgfX0KCiAgICAgICMgU2FtZSBpbi1mbGlnaHQgZ3VhcmQgYXMgdGhlIHJlbGVhc2Ugam9iOiBuZXZlciBjYW5jZWwgYSBoZWFsdGh5CiAgICAgICMgc2FtZS1TSEEgYnVpbGQgYnkgcmUtZGlzcGF0Y2hpbmcgb3ZlciBpdC4KICAgICAgLSBuYW1lOiBDaGVjayBmb3IgaW4tZmxpZ2h0IHByZXJlbGVhc2UgYnVpbGQKICAgICAgICBpZDogaW5mbGlnaHQKICAgICAgICBydW46IHwKICAgICAgICAgIGNvdW50PSQoY3VybCAtLWZhaWwgLS1zaWxlbnQgLS1zaG93LWVycm9yIC0tbG9jYXRpb24gXAogICAgICAgICAgICAtLWhlYWRlciAiQXV0aG9yaXphdGlvbjogdG9rZW4gJHt7IHNlY3JldHMuRElTUEFUQ0hfVE9LRU4gfX0iIFwKICAgICAgICAgICAgLS11cmwgIiR7eyBnaXRodWIuc2VydmVyX3VybCB9fS9hcGkvdjEvcmVwb3MvJHt7IGdpdGh1Yi5yZXBvc2l0b3J5IH19L2FjdGlvbnMvcnVucz9saW1pdD01MCIgXAogICAgICAgICAgICB8IGpxICdbLndvcmtmbG93X3J1bnNbXQogICAgICAgICAgICAgICAgICAgfCBzZWxlY3QoLnBhdGggfCBlbmRzd2l0aCgiYnVpbGQtcHJlcmVsZWFzZS55bWwiKSkKICAgICAgICAgICAgICAgICAgIHwgc2VsZWN0KC5zdGF0dXMgIT0gImNvbXBsZXRlZCIpXSB8IGxlbmd0aCcpCiAgICAgICAgICBlY2hvICJjb3VudD0ke2NvdW50fSIgPj4gIiRHSVRIVUJfT1VUUFVUIgogICAgICAgICAgZWNobyAiaW4tZmxpZ2h0IGJ1aWxkLXByZXJlbGVhc2UgcnVuczogJHtjb3VudH0iCgogICAgICAtIG5hbWU6IFRyaWdnZXIgcHJlcmVsZWFzZSBidWlsZCB3b3JrZmxvdwogICAgICAgIGlmOiBzdGVwcy5wdWJsaXNoZWQub3V0cHV0cy5hbHJlYWR5X2J1aWx0ID09ICdmYWxzZScgJiYgc3RlcHMuaW5mbGlnaHQub3V0cHV0cy5jb3VudCA9PSAnMCcKICAgICAgICBydW46IHwKICAgICAgICAgIGN1cmwgLS1mYWlsIC0tc2lsZW50IC0tc2hvdy1lcnJvciAtLWxvY2F0aW9uIFwKICAgICAgICAgICAgLS1yZXF1ZXN0IFBPU1QgXAogICAgICAgICAgICAtLWhlYWRlciAiQXV0aG9yaXphdGlvbjogdG9rZW4gJHt7IHNlY3JldHMuRElTUEFUQ0hfVE9LRU4gfX0iIFwKICAgICAgICAgICAgLS1oZWFkZXIgJ0NvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vanNvbicgXAogICAgICAgICAgICAtLXVybCAiJHt7IGdpdGh1Yi5zZXJ2ZXJfdXJsIH19L2FwaS92MS9yZXBvcy8ke3sgZ2l0aHViLnJlcG9zaXRvcnkgfX0vYWN0aW9ucy93b3JrZmxvd3MvYnVpbGQtcHJlcmVsZWFzZS55bWwvZGlzcGF0Y2hlcyIgXAogICAgICAgICAgICAtLWRhdGEgIntcInJlZlwiOlwicmVmcy9oZWFkcy9tYWluXCIsXCJpbnB1dHNcIjp7XCJjb21taXRcIjpcIiR7eyBzdGVwcy51cHN0cmVhbS5vdXRwdXRzLnNoYSB9fVwiLFwidmVyc2lvblwiOlwiJHt7IHN0ZXBzLnZlcnNpb24ub3V0cHV0cy52ZXJzaW9uIH19XCIsXCJkYXRlXCI6XCIke3sgc3RlcHMudXBzdHJlYW0ub3V0cHV0cy5kYXRlIH19XCIsXCJzaG9ydF9zaGFcIjpcIiR7eyBzdGVwcy51cHN0cmVhbS5vdXRwdXRzLnNob3J0X3NoYSB9fVwifX0iCg== \ No newline at end of file