Sync with upstream #278
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: Bump ocv track for ocv PRs | |
| env: | |
| GH_TOKEN: ${{ secrets.SYNC_PAT }} | |
| run: | | |
| previous=$(gh release list --repo ${{ github.repository }} --limit 200 --json tagName -q 'map(.tagName | select(test("^v[0-9]+\\.[0-9]+\\.[0-9]+-ocv\\.[0-9]+\\.[0-9]+$"))) | .[0] // ""') | |
| if [ -z "$previous" ]; then | |
| echo "No previous ocv release found, skipping track bump" | |
| exit 0 | |
| fi | |
| git rev-parse --verify --quiet "$previous^{commit}" >/dev/null || git fetch origin "refs/tags/$previous:refs/tags/$previous" | |
| track=$(tr -d '[:space:]' < .github/ocv-track) | |
| if ! printf '%s' "$track" | grep -Eq '^[0-9]+\.[0-9]+$'; then | |
| echo "Invalid ocv track: '$track'" | |
| exit 1 | |
| fi | |
| previous_track="${previous##*-ocv.}" | |
| if [ "$track" != "$previous_track" ]; then | |
| echo "ocv track is already bumped from $previous_track to $track" | |
| exit 0 | |
| fi | |
| prs=$(mktemp) | |
| git log --first-parent --reverse --format='%H' "$previous"..HEAD | while read -r sha; do | |
| gh api "repos/${{ github.repository }}/commits/$sha/pulls" -q '.[] | select(.base.ref == "ocv") | "#\(.number) \(.title)"' || true | |
| done | awk '!seen[$1]++' > "$prs" | |
| if [ ! -s "$prs" ]; then | |
| echo "No ocv PRs merged since $previous" | |
| exit 0 | |
| fi | |
| next="${track%.*}.$((10#${track#*.} + 1))" | |
| printf '%s\n' "$next" > .github/ocv-track | |
| git add .github/ocv-track | |
| git commit -m "release: bump ocv-track" | |
| echo "Bumped ocv track from $track to $next for ocv PRs merged since $previous:" | |
| cat "$prs" | |
| - 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 |