Merge branch 'fix_missed_calculate_looping_components_' into integration

This commit is contained in:
J. Nick Koston 2025-07-22 15:57:15 -10:00
commit 9bceed2cfc
No known key found for this signature in database
5 changed files with 48 additions and 37 deletions

View File

@ -182,11 +182,14 @@ jobs:
}); });
// Check for previous comments from this workflow to avoid duplicate pings // Check for previous comments from this workflow to avoid duplicate pings
const { data: comments } = await github.rest.issues.listComments({ const comments = await github.paginate(
github.rest.issues.listComments,
{
owner, owner,
repo, repo,
issue_number: pr_number issue_number: pr_number
}); }
);
const previouslyPingedUsers = new Set(); const previouslyPingedUsers = new Set();
const previouslyPingedTeams = new Set(); const previouslyPingedTeams = new Set();
@ -194,7 +197,6 @@ jobs:
// Look for comments from github-actions bot that contain our bot marker // Look for comments from github-actions bot that contain our bot marker
const workflowComments = comments.filter(comment => const workflowComments = comments.filter(comment =>
comment.user.type === 'Bot' && comment.user.type === 'Bot' &&
comment.user.login === 'github-actions[bot]' &&
comment.body.includes(BOT_COMMENT_MARKER) comment.body.includes(BOT_COMMENT_MARKER)
); );

View File

@ -61,7 +61,8 @@ jobs:
} }
async function createComment(octokit, owner, repo, prNumber, esphomeChanges, componentChanges) { async function createComment(octokit, owner, repo, prNumber, esphomeChanges, componentChanges) {
const commentMarker = "<!-- This comment was generated automatically by a GitHub workflow. -->"; const commentMarker = "<!-- This comment was generated automatically by the external-component-bot workflow. -->";
const legacyCommentMarker = "<!-- This comment was generated automatically by a GitHub workflow. -->";
let commentBody; let commentBody;
if (esphomeChanges.length === 1) { if (esphomeChanges.length === 1) {
commentBody = generateExternalComponentInstructions(prNumber, componentChanges, owner, repo); commentBody = generateExternalComponentInstructions(prNumber, componentChanges, owner, repo);
@ -71,14 +72,23 @@ jobs:
commentBody += `\n\n---\n(Added by the PR bot)\n\n${commentMarker}`; commentBody += `\n\n---\n(Added by the PR bot)\n\n${commentMarker}`;
// Check for existing bot comment // Check for existing bot comment
const comments = await github.rest.issues.listComments({ const comments = await github.paginate(
github.rest.issues.listComments,
{
owner: owner, owner: owner,
repo: repo, repo: repo,
issue_number: prNumber, issue_number: prNumber,
}); per_page: 100,
}
);
const botComment = comments.data.find(comment => const sorted = comments.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at));
comment.body.includes(commentMarker)
const botComment = sorted.find(comment =>
(
comment.body.includes(commentMarker) ||
comment.body.includes(legacyCommentMarker)
) && comment.user.type === "Bot"
); );
if (botComment && botComment.body === commentBody) { if (botComment && botComment.body === commentBody) {

View File

@ -29,6 +29,9 @@ jobs:
console.log(`Processing issue #${issue_number} with label: ${labelName}`); console.log(`Processing issue #${issue_number} with label: ${labelName}`);
// Hidden marker to identify bot comments from this workflow
const BOT_COMMENT_MARKER = '<!-- issue-codeowner-notify-bot -->';
// Extract component name from label // Extract component name from label
const componentName = labelName.replace('component: ', ''); const componentName = labelName.replace('component: ', '');
console.log(`Component: ${componentName}`); console.log(`Component: ${componentName}`);
@ -93,11 +96,14 @@ jobs:
); );
// Check for previous comments from this workflow to avoid duplicate pings // Check for previous comments from this workflow to avoid duplicate pings
const { data: comments } = await github.rest.issues.listComments({ const comments = await github.paginate(
github.rest.issues.listComments,
{
owner, owner,
repo, repo,
issue_number: issue_number issue_number: issue_number
}); }
);
const previouslyPingedUsers = new Set(); const previouslyPingedUsers = new Set();
const previouslyPingedTeams = new Set(); const previouslyPingedTeams = new Set();
@ -105,9 +111,8 @@ jobs:
// Look for comments from github-actions bot that contain codeowner pings for this component // Look for comments from github-actions bot that contain codeowner pings for this component
const workflowComments = comments.filter(comment => const workflowComments = comments.filter(comment =>
comment.user.type === 'Bot' && comment.user.type === 'Bot' &&
comment.user.login === 'github-actions[bot]' && comment.body.includes(BOT_COMMENT_MARKER) &&
comment.body.includes(`component: ${componentName}`) && comment.body.includes(`component: ${componentName}`)
comment.body.includes("you've been identified as a codeowner")
); );
// Extract previously mentioned users and teams from workflow comments // Extract previously mentioned users and teams from workflow comments
@ -140,7 +145,7 @@ jobs:
// Create comment body // Create comment body
const mentionString = allMentions.join(', '); const mentionString = allMentions.join(', ');
const commentBody = `👋 Hey ${mentionString}!\n\nThis issue has been labeled with \`component: ${componentName}\` and you've been identified as a codeowner of this component. Please take a look when you have a chance!\n\nThanks for maintaining this component! 🙏`; const commentBody = `${BOT_COMMENT_MARKER}\n👋 Hey ${mentionString}!\n\nThis issue has been labeled with \`component: ${componentName}\` and you've been identified as a codeowner of this component. Please take a look when you have a chance!\n\nThanks for maintaining this component! 🙏`;
// Post comment // Post comment
await github.rest.issues.createComment({ await github.rest.issues.createComment({

View File

@ -55,6 +55,9 @@ void Application::setup() {
return a->get_actual_setup_priority() > b->get_actual_setup_priority(); return a->get_actual_setup_priority() > b->get_actual_setup_priority();
}); });
// Initialize looping_components_ early so enable_pending_loops_() works during setup
this->calculate_looping_components_();
for (uint32_t i = 0; i < this->components_.size(); i++) { for (uint32_t i = 0; i < this->components_.size(); i++) {
Component *component = this->components_[i]; Component *component = this->components_[i];
@ -97,7 +100,6 @@ void Application::setup() {
clear_setup_priority_overrides(); clear_setup_priority_overrides();
this->schedule_dump_config(); this->schedule_dump_config();
this->calculate_looping_components_();
} }
void Application::loop() { void Application::loop() {
uint8_t new_app_state = 0; uint8_t new_app_state = 0;
@ -269,24 +271,16 @@ void Application::calculate_looping_components_() {
// Pre-reserve vector to avoid reallocations // Pre-reserve vector to avoid reallocations
this->looping_components_.reserve(total_looping); this->looping_components_.reserve(total_looping);
// First add all active components // Add all components with loop override
// When called at start of setup, all components are in CONSTRUCTION state
// so none will be LOOP_DONE yet - they'll all go in the active section
for (auto *obj : this->components_) { for (auto *obj : this->components_) {
if (obj->has_overridden_loop() && if (obj->has_overridden_loop()) {
(obj->get_component_state() & COMPONENT_STATE_MASK) != COMPONENT_STATE_LOOP_DONE) {
this->looping_components_.push_back(obj); this->looping_components_.push_back(obj);
} }
} }
this->looping_components_active_end_ = this->looping_components_.size(); this->looping_components_active_end_ = this->looping_components_.size();
// Then add all inactive (LOOP_DONE) components
// This handles components that called disable_loop() during setup, before this method runs
for (auto *obj : this->components_) {
if (obj->has_overridden_loop() &&
(obj->get_component_state() & COMPONENT_STATE_MASK) == COMPONENT_STATE_LOOP_DONE) {
this->looping_components_.push_back(obj);
}
}
} }
void Application::disable_component_loop_(Component *component) { void Application::disable_component_loop_(Component *component) {

View File

@ -29,7 +29,7 @@ namespace esphome {
// Base lock-free queue without task notification // Base lock-free queue without task notification
template<class T, uint8_t SIZE> class LockFreeQueue { template<class T, uint8_t SIZE> class LockFreeQueue {
public: public:
LockFreeQueue() : head_(0), tail_(0), dropped_count_(0) {} LockFreeQueue() : dropped_count_(0), head_(0), tail_(0) {}
bool push(T *element) { bool push(T *element) {
bool was_empty; bool was_empty;