From e4aada10a400552f63ba4cda11371841071bdf24 Mon Sep 17 00:00:00 2001 From: Nayan Date: Sun, 26 Oct 2025 21:43:30 -0400 Subject: [PATCH 1/4] Bug: Model UI Crash Fix (#1431) Model UI Crash Fix --- selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc index c3f795e18c..4d89ea58b0 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/models_panel.cc @@ -310,9 +310,8 @@ void ModelsPanel::handleCurrentModelLblBtnClicked() { QList sortedModels; QSet modelFolders; QRegularExpression re("\\(([^)]*)\\)[^(]*$"); - const auto bundles = model_manager.getAvailableBundles(); - for (const auto &bundle : bundles) { + for (const auto &bundle : model_manager.getAvailableBundles()) { auto overrides = bundle.getOverrides(); QString folder; for (const auto &override : overrides) { @@ -392,7 +391,7 @@ void ModelsPanel::handleCurrentModelLblBtnClicked() { showResetParamsDialog(); } else { // Find selected bundle and initiate download - for (const auto &bundle: bundles) { + for (const auto &bundle: model_manager.getAvailableBundles()) { if (QString::fromStdString(bundle.getRef()) == selectedBundleRef) { params.put("ModelManager_DownloadIndex", std::to_string(bundle.getIndex())); if (bundle.getGeneration() != model_manager.getActiveBundle().getGeneration()) { From de7acc54660a9886cc872b17af1e2cbf02285f0b Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Tue, 28 Oct 2025 16:01:21 +0100 Subject: [PATCH 2/4] ci: integrate Discourse notifications and refactor notification logic (#1435) * ci: integrate Discourse notifications and refactor notification logic - Replaced Discord webhook notifications with Discourse topic updates. - Introduced reusable `post-to-discourse` composite action. - Added `test-discourse.yaml` workflow for debugging and verification. * ci: adjust notification dependencies and prepare_strategy reference - Updated `notify` step to depend on `prepare_strategy` instead of `build`. - Adjusted variable references to use `prepare_strategy` outputs. * Forcing debug * ci: update environment variable references and add commit information - Switched `PUBLIC_REPO_URL` source to environment variable for consistency. - Added commit SHA variables to enhance template generation logic. * more tweaks! * more tweaks! * bad bot lmao * Test? * i mean.... * i mean.... * getting there * testing the if * testing the if * ci: re-enable notify steps for prebuilt workflow - Uncommented `build` and `publish` dependencies. - Restored conditional logic to trigger only for relevant events. * ci: enhance Discourse action to support new topic creation - Added support for creating new topics with `category-id` and `title`. - Improved input validation and response handling for flexibility. * ci: improve conditions for prebuilt workflow notifications - Refined `if` clause to ensure branches in `DEV_FEEDBACK_NOTIFICATION_BRANCHES` are targeted. - Adjusted logic for accurate topic ID mapping in Discourse integration. * forgot to rename --- .../workflows/post-to-discourse/action.yml | 105 ++++++++++++++++++ .../workflows/sunnypilot-build-prebuilt.yaml | 63 +++++++---- .github/workflows/test-discourse.yaml.yml | 78 +++++++++++++ 3 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 .github/workflows/post-to-discourse/action.yml create mode 100644 .github/workflows/test-discourse.yaml.yml diff --git a/.github/workflows/post-to-discourse/action.yml b/.github/workflows/post-to-discourse/action.yml new file mode 100644 index 0000000000..55232ce0e1 --- /dev/null +++ b/.github/workflows/post-to-discourse/action.yml @@ -0,0 +1,105 @@ +name: 'Post to Discourse' +description: 'Posts a message to a Discourse topic (existing or new)' + +inputs: + discourse-url: + description: 'Discourse instance URL (e.g., https://discourse.example.com)' + required: true + api-key: + description: 'Discourse API key' + required: true + api-username: + description: 'Discourse API username' + required: true + topic-id: + description: 'Discourse topic ID to post to (use this OR category-id + title)' + required: false + category-id: + description: 'Category ID for new topic (required if topic-id not provided)' + required: false + title: + description: 'Title for new topic (required if topic-id not provided)' + required: false + message: + description: 'Message content (markdown supported)' + required: true + +outputs: + post-number: + description: 'The post number in the topic' + value: ${{ steps.post.outputs.post_number }} + post-url: + description: 'Direct URL to the post' + value: ${{ steps.post.outputs.post_url }} + topic-id: + description: 'The topic ID (useful when creating a new topic)' + value: ${{ steps.post.outputs.topic_id }} + +runs: + using: "composite" + steps: + - name: Post to Discourse + id: post + shell: bash + run: | + # Validate inputs + if [ -z "${{ inputs.topic-id }}" ] && ([ -z "${{ inputs.category-id }}" ] || [ -z "${{ inputs.title }}" ]); then + echo "โŒ Error: Must provide either topic-id OR both category-id and title" + exit 1 + fi + + if [ -n "${{ inputs.topic-id }}" ] && ([ -n "${{ inputs.category-id }}" ] || [ -n "${{ inputs.title }}" ]); then + echo "โš ๏ธ Warning: Both topic-id and category-id/title provided. Will post to existing topic." + fi + + # Determine if creating new topic or posting to existing + if [ -n "${{ inputs.topic-id }}" ]; then + echo "๐Ÿ“ Posting to existing topic ID: ${{ inputs.topic-id }}" + + # Create JSON payload for posting to existing topic + PAYLOAD=$(jq -n \ + --arg content '${{ inputs.message }}' \ + --arg topic_id "${{ inputs.topic-id }}" \ + '{topic_id: $topic_id, raw: $content}') + else + echo "โœจ Creating new topic: ${{ inputs.title }}" + + # Create JSON payload for new topic + PAYLOAD=$(jq -n \ + --arg content '${{ inputs.message }}' \ + --arg title "${{ inputs.title }}" \ + --arg category "${{ inputs.category-id }}" \ + '{title: $title, category: ($category | tonumber), raw: $content}') + fi + + # Post to Discourse + RESPONSE=$(curl -s -w "\n%{http_code}" \ + -X POST "${{ inputs.discourse-url }}/posts.json" \ + -H "Content-Type: application/json" \ + -H "Api-Key: ${{ inputs.api-key }}" \ + -H "Api-Username: ${{ inputs.api-username }}" \ + -d "$PAYLOAD") + + HTTP_CODE=$(echo "$RESPONSE" | tail -n1) + BODY=$(echo "$RESPONSE" | sed '$d') + + if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ]; then + echo "โœ… Successfully posted to Discourse!" + + POST_NUMBER=$(echo "$BODY" | jq -r '.post_number // "unknown"') + TOPIC_ID=$(echo "$BODY" | jq -r '.topic_id // "${{ inputs.topic-id }}"') + POST_URL="${{ inputs.discourse-url }}/t/${TOPIC_ID}/${POST_NUMBER}" + + echo "post_number=${POST_NUMBER}" >> $GITHUB_OUTPUT + echo "post_url=${POST_URL}" >> $GITHUB_OUTPUT + echo "topic_id=${TOPIC_ID}" >> $GITHUB_OUTPUT + + echo "Topic ID: ${TOPIC_ID}" + echo "Post number: ${POST_NUMBER}" + echo "URL: ${POST_URL}" + else + echo "โŒ Failed to post to Discourse" + echo "HTTP Code: ${HTTP_CODE}" + echo "Response: ${BODY}" + exit 1 + fi \ No newline at end of file diff --git a/.github/workflows/sunnypilot-build-prebuilt.yaml b/.github/workflows/sunnypilot-build-prebuilt.yaml index f7719709ae..12fb01cbd1 100644 --- a/.github/workflows/sunnypilot-build-prebuilt.yaml +++ b/.github/workflows/sunnypilot-build-prebuilt.yaml @@ -302,36 +302,51 @@ jobs: git push -f origin ${TAG} notify: - needs: [ build, publish ] + needs: + - prepare_strategy + - build + - publish runs-on: ubuntu-24.04 - if: ${{ (always() && !cancelled() && !failure()) && needs.publish.result == 'success' && !failure() && (!contains(github.event_name, 'pull_request') || (github.event.action == 'labeled' && github.event.label.name == 'prebuilt')) }} + if: ${{ (always() && !cancelled() && !failure()) + && needs.publish.result == 'success' + && (!contains(github.event_name, 'pull_request') || (github.event.action == 'labeled' && github.event.label.name == 'prebuilt')) + && (fromJSON(vars.DEV_FEEDBACK_NOTIFICATION_BRANCHES_V2)[github.head_ref || github.ref_name] != null) }} steps: - uses: actions/checkout@v4 - - name: Setup Alpine Linux environment - uses: jirutka/setup-alpine@v1.2.0 - with: - packages: 'jq gettext curl' - - name: Send Discord Notification - env: - DISCORD_WEBHOOK: ${{ contains(fromJSON(vars.DEV_FEEDBACK_NOTIFICATION_BRANCHES), env.SOURCE_BRANCH) && secrets.DISCORD_DEV_FEEDBACK_CHANNEL_WEBHOOK || secrets.DISCORD_DEV_PRIVATE_CHANNEL_WEBHOOK }} + - name: Prepare notification message + id: message run: | - TEMPLATE='${{ vars.DISCORD_GENERAL_UPDATE_NOTICE }}' - export EXTRA_VERSION_IDENTIFIER="${{ needs.build.outputs.extra_version_identifier }}" - export VERSION="${{ needs.build.outputs.version }}" - export branch_name=${{ env.SOURCE_BRANCH }} - export new_branch=${{ needs.build.outputs.new_branch }} - export extra_version_identifier=${{ needs.build.outputs.extra_version_identifier || github.run_number}} - echo ${TEMPLATE} | envsubst | jq -c '.' | tee payload.json - curl -X POST -H "Content-Type: application/json" -d @payload.json $DISCORD_WEBHOOK + TEMPLATE='${{ vars.DISCOURSE_GENERAL_UPDATE_NOTICE }}' + export VERSION="${{ needs.prepare_strategy.outputs.version }}" + export branch_name="${{ env.SOURCE_BRANCH }}" + export new_branch="${{ needs.prepare_strategy.outputs.new_branch }}" + export commit_sha="${{ github.sha }}" + export commit_short_sha="${{ github.sha }}" + export commit_short_sha="${commit_short_sha:0:7}" + export extra_version_identifier="${{ needs.prepare_strategy.outputs.extra_version_identifier || github.run_number }}" + export PUBLIC_REPO_URL="${{ env.PUBLIC_REPO_URL }}" - echo "" - echo "---- โ„น๏ธ To update the list of branches that notify to dev-feedback -----" - echo "" - echo "1. Go to: ${{ github.server_url }}/${{ github.repository }}/settings/variables/actions/DEV_FEEDBACK_NOTIFICATION_BRANCHES" - echo "2. Current value: ${{ vars.DEV_FEEDBACK_NOTIFICATION_BRANCHES }}" - echo "3. Update as needed (JSON array with no spaces)" - shell: alpine.sh {0} + MESSAGE=$(cat << 'EOF' | envsubst + ${{ vars.DISCOURSE_GENERAL_UPDATE_NOTICE }} + EOF + ) + + { + echo 'content<> $GITHUB_OUTPUT + shell: bash + + - name: Post to Discourse + uses: ./.github/workflows/post-to-discourse + with: + discourse-url: ${{ vars.DISCOURSE_URL }} + api-key: ${{ secrets.DISCOURSE_API_KEY }} + api-username: "system" + topic-id: ${{ fromJSON(vars.DEV_FEEDBACK_NOTIFICATION_BRANCHES_V2)[github.head_ref || github.ref_name].topic_id }} + message: ${{ steps.message.outputs.content }} manage-pr-labels: name: Remove prebuilt label diff --git a/.github/workflows/test-discourse.yaml.yml b/.github/workflows/test-discourse.yaml.yml new file mode 100644 index 0000000000..fadaec4eaa --- /dev/null +++ b/.github/workflows/test-discourse.yaml.yml @@ -0,0 +1,78 @@ +name: Debug Discourse Posting + +on: + push: + +jobs: + test-discourse-post: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Post test message to Discourse + uses: ./.github/workflows/post-to-discourse + with: + discourse-url: ${{ vars.DISCOURSE_URL }} + api-key: ${{ secrets.DISCOURSE_API_KEY }} + api-username: ${{ secrets.DISCOURSE_API_USERNAME }} + topic-id: ${{ vars.DISCOURSE_UPDATES_TOPIC_ID }} + message: | + ## ๐Ÿงช Test Post from GitHub Actions + + **This is a test post to verify Discourse integration** + + - **Workflow**: ${{ github.workflow }} + - **Run Number**: #${{ github.run_number }} + - **Branch**: `${{ github.ref_name }}` + - **Commit**: ${{ github.sha }} + - **Actor**: @${{ github.actor }} + - **Timestamp**: ${{ github.event.head_commit.timestamp }} + + --- + + ### Fake Build Info (for testing) + - **Version**: 0.9.8-test + - **Build**: #42 + - **Branch**: release-test + + [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + *This is an automated test message. Drive safe! ๐Ÿš—๐Ÿ’จ* + + + - name: Create topic on Discourse + uses: ./.github/workflows/post-to-discourse + with: + discourse-url: ${{ vars.DISCOURSE_URL }} + api-key: ${{ secrets.DISCOURSE_API_KEY }} + api-username: ${{ secrets.DISCOURSE_API_USERNAME }} + #topic-id: ${{ vars.DISCOURSE_UPDATES_TOPIC_ID }} + category-id: 4 + title: "This is a test of a new topic instead of a reply" + message: | + ## ๐Ÿงช Test Post from GitHub Actions + + **This is a test post to verify Discourse integration** + + - **Workflow**: ${{ github.workflow }} + - **Run Number**: #${{ github.run_number }} + - **Branch**: `${{ github.ref_name }}` + - **Commit**: ${{ github.sha }} + - **Actor**: @${{ github.actor }} + - **Timestamp**: ${{ github.event.head_commit.timestamp }} + + --- + + ### Fake Build Info (for testing) + - **Version**: 0.9.8-test + - **Build**: #42 + - **Branch**: release-test + + [View workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) + + *This is an automated test message. Drive safe! ๐Ÿš—๐Ÿ’จ* + - name: Display results + if: always() + run: | + echo "::notice::Discourse post test completed" + echo "Check your Discourse topic to verify the post appeared correctly" \ No newline at end of file From 55147d8a55e23293a95b353039bc9caeb866ec04 Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Tue, 28 Oct 2025 18:58:04 +0100 Subject: [PATCH 3/4] ci: use environment variable for PR label in query (#1436) * ci: use environment variable for PR label in query - Replaced static `PR_LABEL` references with `${{ env.PR_LABEL }}` for consistency. - Ensures flexibility and reduces hardcoded values in the workflow. * does this work better? * fuck this * aight --- .github/workflows/sunnypilot-master-dev-prep.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sunnypilot-master-dev-prep.yaml b/.github/workflows/sunnypilot-master-dev-prep.yaml index 4aafd4a4a4..968540955f 100644 --- a/.github/workflows/sunnypilot-master-dev-prep.yaml +++ b/.github/workflows/sunnypilot-master-dev-prep.yaml @@ -3,7 +3,6 @@ name: Build dev env: DEFAULT_SOURCE_BRANCH: "master" DEFAULT_TARGET_BRANCH: "master-dev" - PR_LABEL: "dev" LFS_URL: 'https://gitlab.com/sunnypilot/public/sunnypilot-new-lfs.git/info/lfs' LFS_PUSH_URL: 'ssh://git@gitlab.com/sunnypilot/public/sunnypilot-new-lfs.git' @@ -119,7 +118,7 @@ jobs: # Use GitHub API to get PRs with specific label, ordered by creation date PR_LIST=$(gh api graphql -f query=' query($search_query:String!) { - search(query: $search_query, type:ISSUE, first:100) { + search(query: $search_query, type:ISSUE, first:40) { nodes { ... on PullRequest { number @@ -149,7 +148,7 @@ jobs: } } } - }' -F search_query="repo:${{ github.repository }} is:pr is:open label:${PR_LABEL},${PR_LABEL}-c3 draft:false sort:created-asc") + }' -F search_query="repo:${{ github.repository }} is:pr is:open label:${{ vars.PREBUILT_PR_LABEL }},${{ vars.PREBUILT_PR_LABEL }}-c3 draft:false sort:created-asc") PR_LIST=${PR_LIST//\'/} echo "PR_LIST=${PR_LIST}" >> $GITHUB_OUTPUT From 707e2aedae4ddc872c609df1ae7c9e3f1e8738cd Mon Sep 17 00:00:00 2001 From: THERoenPR Date: Tue, 28 Oct 2025 22:13:39 -0400 Subject: [PATCH 4/4] controlsd: add `CP_SP` to `get_pid_accel_limits` (#1410) * Add CP_SP to get_pid_accel_limits() call in controlsd Match input parameters of CP_SP commit * bump * bump --------- Co-authored-by: roenthomas <43324106+roenthomas@users.noreply.github.com> Co-authored-by: Jason Wen --- opendbc_repo | 2 +- selfdrive/controls/controlsd.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index efe4ff137f..e0e1626820 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit efe4ff137f839bbd416ac8ff8f5b78550a7d6eec +Subproject commit e0e1626820d6a18a984ae69eebc012180699d41c diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 1694afee23..b381879a7a 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -132,7 +132,7 @@ class Controls(ControlsExt, ModelStateBase): self.LoC.reset() # accel PID loop - pid_accel_limits = self.CI.get_pid_accel_limits(self.CP, CS.vEgo, CS.vCruise * CV.KPH_TO_MS) + pid_accel_limits = self.CI.get_pid_accel_limits(self.CP, self.CP_SP, CS.vEgo, CS.vCruise * CV.KPH_TO_MS) actuators.accel = float(self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits)) # Steering PID loop and lateral MPC