Sync with upstream #253
This file contains hidden or 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
| name: Sync with upstream | |
| on: | |
| schedule: | |
| - cron: "0 */6 * * *" | |
| workflow_dispatch: | |
| concurrency: | |
| group: sync-upstream | |
| cancel-in-progress: false | |
| jobs: | |
| sync: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ocv | |
| fetch-depth: 0 | |
| token: ${{ secrets.SYNC_PAT }} | |
| - name: Merge upstream/dev | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git remote add upstream https://github.com/sst/opencode.git | |
| git fetch upstream dev | |
| git merge --no-edit upstream/dev | |
| - name: Push | |
| run: git push origin ocv | |
| - name: Disable upstream workflows | |
| env: | |
| GH_TOKEN: ${{ secrets.SYNC_PAT }} | |
| run: | | |
| keep="ci.yml publish-ocv.yml sync-upstream.yml" | |
| gh api repos/${{ github.repository }}/actions/workflows --paginate -q '.workflows[] | "\(.id) \(.path)"' | while read id path; do | |
| name=$(basename "$path") | |
| if echo "$keep" | grep -qw "$name"; then | |
| continue | |
| fi | |
| gh api -X PUT "repos/${{ github.repository }}/actions/workflows/$id/disable" 2>/dev/null || true | |
| done | |
| - name: Check for new upstream version | |
| id: version | |
| env: | |
| GH_TOKEN: ${{ secrets.SYNC_PAT }} | |
| run: | | |
| upstream=$(gh release list --repo sst/opencode --exclude-drafts --exclude-pre-releases --limit 200 --json tagName -q 'map(.tagName | select(test("^v[0-9]+\\.[0-9]+\\.[0-9]+$"))) | .[0] // ""' | sed 's/^v//') | |
| current=$(gh release list --repo ${{ github.repository }} --limit 200 --json tagName -q 'map(.tagName | sub("^v"; "")) | map(select(test("^[0-9]+\\.[0-9]+\\.[0-9]+-ocv\\.[0-9]+\\.[0-9]+$"))) | .[0] // ""') | |
| track=$(tr -d '[:space:]' < .github/ocv-track) | |
| upstream_base=$(echo "$upstream" | sed -E 's/-(vim|ocv)\..*$//') | |
| current_base=$(echo "$current" | sed -E 's/-(vim|ocv)\..*$//') | |
| if ! printf '%s' "$track" | grep -Eq '^[0-9]+\.[0-9]+$'; then | |
| echo "Invalid ocv track: '$track'" | |
| exit 1 | |
| fi | |
| release="${upstream_base}-ocv.${track}" | |
| exists=$(gh release view "v$release" --repo ${{ github.repository }} >/dev/null 2>&1 && printf true || printf false) | |
| echo "upstream=$upstream" | |
| echo "current=$current" | |
| echo "track=$track" | |
| echo "upstream_base=$upstream_base" | |
| echo "current_base=$current_base" | |
| echo "release=$release" | |
| echo "exists=$exists" | |
| echo "upstream=$upstream" >> "$GITHUB_OUTPUT" | |
| echo "current=$current" >> "$GITHUB_OUTPUT" | |
| echo "track=$track" >> "$GITHUB_OUTPUT" | |
| echo "upstream_base=$upstream_base" >> "$GITHUB_OUTPUT" | |
| echo "current_base=$current_base" >> "$GITHUB_OUTPUT" | |
| echo "release=$release" >> "$GITHUB_OUTPUT" | |
| echo "exists=$exists" >> "$GITHUB_OUTPUT" | |
| - name: Trigger release | |
| if: steps.version.outputs.upstream_base != '' && steps.version.outputs.release != steps.version.outputs.current && steps.version.outputs.exists != 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.SYNC_PAT }} | |
| run: gh workflow run publish-ocv.yml --repo ${{ github.repository }} --ref ocv -f version=${{ steps.version.outputs.release }} | |
| - name: Close failure issue on success | |
| if: success() | |
| env: | |
| GH_TOKEN: ${{ secrets.SYNC_PAT }} | |
| run: | | |
| issues=$(gh issue list --repo ${{ github.repository }} --state open --limit 1000 --json number,title -q '.[] | select(.title == "[ci]: sync upstream failed" or .title == "[actions]: sync upstream failed") | .number') | |
| if [ -z "$issues" ]; then | |
| exit 0 | |
| fi | |
| printf '%s\n' "$issues" | while read -r number; do | |
| gh issue close "$number" --repo ${{ github.repository }} --comment "Closed automatically after a successful sync run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
| done | |
| - name: Notify on failure | |
| if: failure() | |
| env: | |
| GH_TOKEN: ${{ secrets.SYNC_PAT }} | |
| run: | | |
| issues=$(gh issue list --repo ${{ github.repository }} --state open --limit 1000 --json number,title -q '.[] | select(.title == "[ci]: sync upstream failed" or .title == "[actions]: sync upstream failed") | [.number, .title] | @tsv') | |
| tracker=$(printf '%s\n' "$issues" | awk -F '\t' '$2 == "[ci]: sync upstream failed" { print $1; exit }') | |
| if [ -z "$tracker" ]; then | |
| tracker=$(printf '%s\n' "$issues" | awk -F '\t' 'NF { print $1; exit }') | |
| if [ -n "$tracker" ]; then | |
| gh issue edit "$tracker" --repo ${{ github.repository }} --title "[ci]: sync upstream failed" | |
| fi | |
| fi | |
| if [ -z "$tracker" ]; then | |
| gh issue create --repo ${{ github.repository }} \ | |
| --title "[ci]: sync upstream failed" \ | |
| --body "Sync workflow failed. Likely a merge conflict. [View run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" | |
| exit 0 | |
| fi | |
| printf '%s\n' "$issues" | awk -F '\t' -v tracker="$tracker" 'NF && $1 != tracker { print $1 }' | while read -r number; do | |
| gh issue close "$number" --repo ${{ github.repository }} --comment "Closing duplicate; tracking this failure in #$tracker." | |
| done |