{"id":15355568,"url":"https://github.com/mattipv4/hacktoberfest-data","last_synced_at":"2025-02-27T02:31:10.134Z","repository":{"id":40795851,"uuid":"219971008","full_name":"MattIPv4/hacktoberfest-data","owner":"MattIPv4","description":"Generating stats from the raw Hacktoberfest application data.","archived":true,"fork":false,"pushed_at":"2023-11-30T19:35:15.000Z","size":30573,"stargazers_count":19,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-17T03:44:39.314Z","etag":null,"topics":["canvasjs","chart","charts","graph","graphics","graphs","hacktoberfest","mongodb","node","nodejs","statistics","stats"],"latest_commit_sha":null,"homepage":"https://hacktoberfest.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MattIPv4.png","metadata":{"files":{"readme":"README.dot.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"MattIPv4","patreon":"IPv4","ko_fi":"MattIPv4","custom":"https://paypal.me/MattIPv4Cowley"}},"created_at":"2019-11-06T10:28:49.000Z","updated_at":"2024-11-04T20:44:57.000Z","dependencies_parsed_at":"2024-10-16T03:21:12.323Z","dependency_job_id":"648c4f52-9426-4107-86f4-2b88ac90228a","html_url":"https://github.com/MattIPv4/hacktoberfest-data","commit_stats":{"total_commits":150,"total_committers":2,"mean_commits":75.0,"dds":0.09333333333333338,"last_synced_commit":"11d29b1c826b4448a8ea3ea8db67a7f179037c9a"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MattIPv4%2Fhacktoberfest-data","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MattIPv4%2Fhacktoberfest-data/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MattIPv4%2Fhacktoberfest-data/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MattIPv4%2Fhacktoberfest-data/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MattIPv4","download_url":"https://codeload.github.com/MattIPv4/hacktoberfest-data/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240966381,"owners_count":19886066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canvasjs","chart","charts","graph","graphics","graphs","hacktoberfest","mongodb","node","nodejs","statistics","stats"],"created_at":"2024-10-01T12:24:48.834Z","updated_at":"2025-02-27T02:31:09.663Z","avatar_url":"https://github.com/MattIPv4.png","language":"JavaScript","funding_links":["https://github.com/sponsors/MattIPv4","https://patreon.com/IPv4","https://ko-fi.com/MattIPv4","https://paypal.me/MattIPv4Cowley"],"categories":[],"sub_categories":[],"readme":"# Hacktoberfest {{= data.readme.year }} Stats\n\nHi there, 👋\n\nI'm [Matt Cowley](https://mattcowley.co.uk/), Senior Software Engineer II at\n[DigitalOcean](https://digitalocean.com/).\n\nI work on a bunch of things at DigitalOcean, with a great mix of engineering, developer relations\nand community management. And, part of what I get to work on is helping out with Hacktoberfest,\nincluding being the lead engineer for the backend that powers the event.\n\nWelcome to my deeper dive on the data and stats for Hacktoberfest {{= data.readme.year }}, expanding\non what we already shared in our [recap blog post](https://{{= data.readme.blog }}).\n\n## At a glance\n\nWhat did we accomplish together in October {{= data.readme.year }}?\nThese are the highlights from Hacktoberfest #{{= data.readme.year - 2013 }}:\n\n- Registered users: **{{= c(data.readme.registeredUsers) }}**\n- Engaged users (1-3 accepted PR/MRs): **{{= c(data.readme.engagedUsers) }}**\n- Completed users (4+ accepted PR/MRs): **{{= c(data.readme.completedUsers) }}**\n- Accepted PR/MRs: **{{= c(data.readme.acceptedPRs) }}**\n- Active repositories (1+ accepted PR/MRs): **{{= c(data.readme.activeRepos) }}**\n- Countries represented by registered users: **{{= c(data.readme.countriesRegistered) }}**\n- Countries represented by completed users: **{{= c(data.readme.countriesCompleted) }}**\n\n\u003e Take a read of our overall recap blog post for Hacktoberfest {{= data.readme.year }} here:\n\u003e [{{= data.readme.blog }}](https://{{= data.readme.blog }})\n\n## Application states\n\nBefore jumping in and looking at the data in detail, we should first cover some important\ninformation about how we categorise users and pull/merge requests in the Hacktoberfest application\nand in the data used here.\n\nFor users, there are four key states that you'll see:\n\n- **Completed**: A user that submitted four or more accepted PR/MRs during Hacktoberfest.\n- **Engaged**: A user that submitted between one and three accepted PR/MRs during Hacktoberfest.\n- **Registered**: A user that completed the registration flow for Hacktoberfest, but did not submit\n  any PR/MRs that were accepted.\n- **Disqualified**: A user that was disqualified for submitting 2 or more spammy PR/MRs,\n  irrespective of how many accepted PR/MRs they may have also had.\n\nFor pull/merge requests, there are six states used to process them that you'll see:\n\n- **Accepted**: A PR/MR that was accepted by a project maintainer, either by being merged or\n  approved in a participating repository, or by being given the `hacktoberfest-accepted` label.\n- **Not accepted**: Any PR/MR that was submitted to a participating repository (having the\n  `hacktoberfest` topic), but that was not actively accepted by a maintainer.\n- **Not participating**: Any PR/MR that was submitted by a participant to a repository that was not\n  participating in Hacktoberfest (i.e. having the `hacktoberfest` topic, or adding the\n  `hacktoberfest-accepted` label to specific PRs).\n- **Invalid**: Any PR/MR that was given a label containing the word `invalid` by a maintainer. Any\n  PR/MR with a matching label was not counted towards a participant's total.\n- **Spam**: Any PR/MR that was given a label by a maintainer containing the 'spam', or PR/MRs that \n  our abuse logic detected as spam. These are not counted toward winning, and also count toward a\n  user being disqualified.\n- **Excluded**: Any PR/MR that was submitted to a repository that has been excluded from\n  Hacktoberfest for not following our values. These do not count toward winning, nor do they count\n  toward a user being disqualified.\n\n## Diving in: Users\n\nThis year, Hacktoberfest had **{{= c(data.Users.totalUsers) }}** folks who went through our\nregistration flow for the event. Spam has been a huge focus for us throughout the event, as with\nprevious years, and so during this flow folks were reminded about our rules and values for the event\nwith clear and simple language, as well as agreeing to a rule that folks with two or more PR/MRs\nidentified as spam by maintainers would be disqualified. More on this later.\n\nDuring the registration flow, folks can also choose to tell us which country they are from--this\nhelps us better understand, and cater to, the global audience for the event--and\n**{{= p((data.Users.totalUsers - data.Users.totalUsersNoCountry) / data.Users.totalUsers) }}** of\nthem did so.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"generated/users_completions_top_countries_bar.png\" width=\"45%\" alt=\"Bar chart of the top countries for completed users\" /\u003e\n  \u003cimg src=\"generated/users_registrations_top_countries_bar.png\" width=\"45%\" alt=\"Bar chart of the top countries for all registered users\" /\u003e\n\u003c/p\u003e\n\nThe top country, by far, was once again {{= data.Users.totalUsersByCountry[0][0] }} with\n**{{= c(data.Users.totalUsersByCountry[0][1]) }}\n({{= p(data.Users.totalUsersByCountry[0][1] / data.Users.totalUsers) }})** registrants\nself-identifying as being from there, showing how much of a reach open-source, and tech in general,\nhas there.\n\nWe can see the true global reach of Hacktoberfest and open-source by looking at more of the top\ncountries based on registrations:\n\n{{~ data.Users.totalUsersByCountry.slice(0, 10) :item:i }}\n{{= i + 1 }}. {{= item[0] }}: {{= c(item[1]) }} ({{= p(item[1] / data.Users.totalUsers) }})\n{{~ }}\n\nIn total, **{{= c(data.Users.totalUsersByCountry.length) }} countries** were represented by folks\nthat registered for the {{= data.readme.year }} event.\n\nWe can also look at just the users that completed Hacktoberfest, and see how the countries are\ndistributed for those users:\n\n{{~ data.Users.totalUsersCompletedByCountry.slice(0, 10) :item:i }}\n{{= i + 1 }}. {{= item[0] }}: {{= c(item[1]) }} ({{= p(item[1] / data.Users.totalUsersCompleted) }})\n{{~ }}\n\n\u003cimg src=\"generated/users_by_state_doughnut.png\" width=\"40%\" align=\"right\" alt=\"Doughnut diagram of users by application state\" /\u003e\n\nOf course, there's more to Hacktoberfest than just registering for the event, folks actually submit\nPR/MRs to open-source projects! This year, we had\n**{{= c(data.Users.totalUsersCompleted + data.Users.totalUsersEngaged) }}\nusers\n({{= p((data.Users.totalUsersCompleted + data.Users.totalUsersEngaged) / data.Users.totalUsers) }}\nof total registrations)** that submitted one or more PR/MRs that were accepted by maintainers.\nOf those, **{{= c(data.Users.totalUsersCompleted) }}\n({{= p(data.Users.totalUsersCompleted / (data.Users.totalUsersCompleted + data.Users.totalUsersEngaged)) }})\n({{= p(data.Users.totalUsersCompleted / data.Users.totalUsers) }} of total registrations)** went on\nto submit at least four accepted PR/MRs to successfully complete Hacktoberfest.\n\nImpressively, we saw that **{{= c(data.Users.totalUsersByAcceptedPRsCapped[4][1]) }} users\n({{= p(data.Users.totalUsersByAcceptedPRsCapped[4][1] / data.Users.totalUsersCompleted) }} of total\ncompleted)** submitted more than 4 accepted PR/MRs, going above and beyond to contribute to\nopen-source outside the goal set for completing Hacktoberfest.\n\nThis year, Hacktoberfest removed the free t-shirt as a reward for completing Hacktoberfest, instead\nreplacing it with a digital reward kit unlocked once you had four accepted PR/MRs, and a digital\nbadge from Holopin that levelled up with each PR/MR accepted on your journey from registration to\ncompletion. While we still saw many folks register and engage with Hacktoberfest, the numbers are\nmuch lower than previous years, likely due to this change in reward, and while disappointing this\nwas expected.\n\nSadly, {{= c(data.Users.totalUsersDisqualified) }} users were disqualified this year\n({{= p(data.Users.totalUsersDisqualified / data.Users.totalUsers) }} of total registrations), with\nan additional {{= c(data.Users.totalUsersWarned) }}\n({{= p(data.Users.totalUsersWarned / data.Users.totalUsers) }} of total registrations) warned.\nDisqualification of users happen automatically if two or more of their PR/MRs are actively\nidentified as spam by project maintainers, with users being sent a warning email (and shown a notice\non their profile) when they have one PR/MR that is identified as spam. We were very happy to see how\nlow this number was though, indicating to us that our efforts to educate and remind contributors of\nthe quality standards expected of them during Hacktoberfest are working. _(Of course, we can only\nreport on what we see in our data here, and do acknowledge that folks may have received spam that\nwasn't flagged so won't be represented in our reporting)._\n\n\u003c!-- Clear for generated/users_by_state_doughnut.png --\u003e\n\u003cp style=\"clear: both;\"\u003e\u003c/p\u003e\n\nHacktoberfest supported multiple providers this year, GitHub \u0026 GitLab. Registrants could choose to\nlink just one provider to their account, or multiple if they desired, with contributions from each\nprovider combined into a single record for the user.\n\nBased on this we can take a look at the most popular providers for open-source based on some\nHacktoberfest-specific metrics. First, we can see that based on registrations, **the most popular\nprovider was {{= data.Users.totalUsersByProvider[0][0] }} with\n{{= c(data.Users.totalUsersByProvider[0][1]) }} registrants\n({{= p(data.Users.totalUsersByProvider[0][1] / data.Users.totalUsers) }}).**\n\n{{~ data.Users.totalUsersByProvider :item:i }}\n{{= i + 1 }}. {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsers) }} of registered users)\n{{~ }}\n\n_Users were able to link one or more providers to their account, so the counts here may sum to more\nthan the total number of users registered._\n\nWe can also look at a breakdown of users that were engaged (1-3 accepted PR/MRs) and users that\ncompleted Hacktoberfest (4+ PR/MRs) by provider.\n\nEngaged users by provider:\n\n{{~ data.Users.totalUsersEngagedByProvider :item:i }}\n- {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsersEngaged) }} of engaged users)\n{{~ }}\n\nCompleted users by provider:\n\n{{~ data.Users.totalUsersCompletedByProvider :item:i }}\n- {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsersCompleted) }} of completed users)\n{{~ }}\n\n\u003cimg src=\"generated/users_registrations_experience_level_bar.png\" width=\"40%\" align=\"right\" alt=\"Bar chart of users by experience level\" /\u003e\n\nWhen registering for Hacktoberfest, we also asked users for some optional self-identification around\ntheir experience with contributing to open-source, and how they intended to contribute. First, we\ncan take a look at the experience level users self-identified as having when registering:\n\n{{~ data.Users.totalUsersByExperience :item:i }}\n- {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsers) }} of registered users)\n{{~ }}\n\n_{{= c(data.Users.totalUsersNoExperience) }} users did not self-identify their experience level._\n\nWe can compare this to the breakdown of users that completed Hacktoberfest by experience level:\n\n{{~ data.Users.totalUsersCompletedByExperience :item:i }}\n- {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsersCompleted) }} of completed users)\n{{~ }}\n\n_{{= c(data.Users.totalUsersCompletedNoExperience) }} users who completed Hacktoberfest did not\nself-identify their experience when registering._\n\n\u003c!-- Clear for generated/users_registrations_experience_level_bar.png --\u003e\n\u003cp style=\"clear: both;\"\u003e\u003c/p\u003e\n\nNot everyone is comfortable writing code, and so Hacktoberfest focused on encouraging more\ncontributors to get involved with open-source this year through non-code contributors. We can look\nat what contribution types users indicated they intended to make during Hacktoberfest when\nregistering (they could pick multiple, or none):\n\n{{~ data.Users.totalUsersByContribution :item:i }}\n- {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsers) }} of registered users)\n{{~ }}\n\n_Of course, this is only what users indicated they intended to do, and doesn't necessarily reflect\ntheir actual contributions they ended up making to open-source (determining what is and what isn't\na \"non-code\" PR/MR would be a difficult task)._\n\nThis year, we also asked users during registration whether they were students or not, to give us a\nbetter sense of the audience that is participating in Hacktoberfest. We can see that\n**{{= c(data.Users.totalUsersStudents) }} users\n({{= p(data.Users.totalUsersStudents / data.Users.totalUsers) }} of registered users)** indicated\nthat they were students when registering.\n\n\u003cimg src=\"generated/users_registrations_ai_ml_interest_bar.png\" width=\"40%\" align=\"right\" alt=\"Bar chart of users by AI/ML interest\" /\u003e\n\nFolks were also asked if they'd be interested in contributing to AI/ML projects specifically during\nHacktoberfest, as this area of open-source is growing rapidly and we wanted to see if there was\ninterest in it.\n\nWe can see that **{{= c(data.Users.totalUsersAIML) }} users\n({{= p(data.Users.totalUsersAIML / data.Users.totalUsers) }} of registered users)** indicated they\nwere actively interested in AI/ML projects, while **{{= c(data.Users.totalUsersNotAIML) }} users\n({{= p(data.Users.totalUsersNotAIML / data.Users.totalUsers) }} of registered users)** indicated\nthey were not interested in AI/ML projects (this was an optional question, with\n{{= c(data.Users.totalUsersMissingAIML) }} users not providing a preference).\n\nWhile we obviously can't know for sure the preference of those that did not interact with this\nquestion, there was a much larger portion of folks registering that did not engage with this\nquestion than other questions ({{= p(data.Users.totalUsersMissingAIML / data.Users.totalUsers) }},\ncompared to just {{= p(data.Users.totalUsersNoExperience / data.Users.totalUsers) }} that did not\nindicate their experience level), which is potentially an indicator that folks were unfamiliar with\nor disinterested in AI/ML.\n\n\u003c!-- Clear for generated/users_registrations_ai_ml_interest_bar.png --\u003e\n\u003cp style=\"clear: both;\"\u003e\u003c/p\u003e\n\nAs with previous years of Hacktoberfest, users had to submit PR/MRs to participating projects during\nOctober that then had to be accepted by maintainers during October. If a user submitted four or\nmore PR/MRs, then they completed Hacktoberfest. However, not everyone hit the 4 PR/MR target, with\nsome falling short, and many going beyond the target to contribute further.\n\nWe can see how many accepted PR/MRs each user had and bucket them:\n\n{{~ data.Users.totalUsersByAcceptedPRs :item:i }}\n- {{= item[0] }}{{= (i === data.Users.totalUsersByAcceptedPRs.length - 1 ? '+' : '') }}\n  PR{{= (item[0] === 1 ? '': 's') }}/MR{{= (item[0] === 1 ? '': 's') }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.Users.totalUsersCompleted) }})\n{{~ }}\n\nLooking at this, we can see that quite a few users only managed to get 1 accepted PR/MR, but\nafter that it quickly trailed off for 2 and 3 PR/MRs. It seems like the target of 4 PR/MRs\nencouraged many users to push through to getting all 4 PR/MRs created/accepted if they got that\nfirst one completed.\n\n![Bar chart of users by accepted PR/MRs](generated/users_by_prs_extended_column.png)\n\n## Diving in: Pull/Merge Requests\n\n\u003cimg src=\"generated/prs_by_state_doughnut.png\" width=\"40%\" align=\"right\" alt=\"Doughnut diagram of PR/MRs by application state\" /\u003e\n\nNow on to what you've been waiting for, and the core of Hacktoberfest itself, the pull/merge\nrequests. This year Hacktoberfest tracked **{{= c(data.PRs.totalPRs) }}** PR/MRs that were within\nthe bounds of the Hacktoberfest event, and **{{= c(data.PRs.totalAcceptedPRs) }}\n({{= p(data.PRs.totalAcceptedPRs / data.PRs.totalPRs) }})** of those went on to be accepted!\n\nUnfortunately, not every pull/merge request can be accepted though, for one reason or another, and\nthis year we saw that there were **{{= c(data.PRs.totalNotAcceptedPRs )}}\n({{= p(data.PRs.totalNotAcceptedPRs / data.PRs.totalPRs) }})** PR/MRs that were submitted to\nparticipating repositories but that were not accepted by maintainers, as well as\n**{{= c(data.PRs.totalNotParticipatingPRs )}}\n({{= p(data.PRs.totalNotParticipatingPRs / data.PRs.totalPRs) }})** PR/MRs submitted by\nHacktoberfest participants to repositories that were not participating in Hacktoberfest. As a\nreminder to folks, repositories opt-in to participating in Hacktoberfest by adding the\n`hacktoberfest` topic to their repository (or individual PR/MRs can be opted-in with the\n`hacktoberfest-accepted` label).\n\nSpam is also a big issue that we focus on reducing during Hacktoberfest, and we tracked the number\nof PR/MRs that were identified by maintainers as spam, as well as those that were caught by\nautomation we'd written to stop spammy users. We'll talk more about all-things-spam later on.\n\n\u003c!-- Clear for generated/prs_by_state_doughnut.png --\u003e\n\u003cp style=\"clear: both;\"\u003e\u003c/p\u003e\n\nThis year, Hacktoberfest supported multiple providers that contributors could use to submit\ncontributions to open-source projects. Let's take a look at the breakdown of PR/MRs per provider:\n\n{{~ data.PRs.totalPRsByProvider :item:i }}\n{{= i + 1 }}. {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.PRs.totalPRs) }} of total PR/MRs)\n{{~ }}\n\nPRs and MRs that are accepted by maintainers for Hacktoberfest aren't necessarily merged --\nHacktoberfest supports multiple different ways for a maintainer to indicate that a PR/MR is\nlegitimate and should be counted. PR/MRs can be merged, or they can be given the\n`hacktoberfest-accepted` label, or maintainers can leave an overall approving review.\n\nOf the accepted PR/MRs, **{{= c(data.PRs.totalAcceptedPRsMerged) }}\n({{= p(data.PRs.totalAcceptedPRsMerged / data.PRs.totalAcceptedPRs) }})** were merged into the\nrepository, and **{{= c(data.PRs.totalAcceptedPRsApproved) }}\n({{= p(data.PRs.totalAcceptedPRsApproved / data.PRs.totalAcceptedPRs) }})** were approved by a\nmaintainer. Note that there may be overlap here, as a PR/MR may have been approved and then merged.\nUnfortunately, we don't have direct aggregated data for the `hacktoberfest-accepted` label.\n\nWith this many accepted PRs, we can also take a look at some interesting averages determined from\nthe accepted PR/MRs. The average accepted PR/MR...\n\n- ...contained **{{= c(data.PRs.averageAcceptedPRCommits) }} commits**\n- ...added/edited/removed **{{= c(data.PRs.averageAcceptedPRFiles) }} files**\n- ...made a total of **{{= c(data.PRs.averageAcceptedPRAdditions) }} additions** _(lines)_\n- ...included **{{= c(data.PRs.averageAcceptedPRDeletions) }} deletions** _(lines)_\n\n_Note that lines containing edits will be counted as both an addition and a deletion._\n\nWe can also take a look at all the different languages that we observed during Hacktoberfest. These\nare based on the primary language reported for the repository, and the number of accepted\nHacktoberfest PRs that were submitted to that repository. Unfortunately, GitLab does not expose\nlanguage information via their API, so this only considers GitHub PRs.\n\n{{~ data.PRs.totalAcceptedPRsByLanguage.slice(0, 10) :item:i }}\n{{= i + 1 }}. {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.PRs.totalAcceptedPRs) }} of all accepted PRs)\n{{~ }}\n\n\u003cimg src=\"generated/prs_by_day_bar.png\" width=\"40%\" align=\"right\" alt=\"Bar chart of accepted PR/MRs by most popular days\" /\u003e\n\nHacktoberfest happens throughout the month of October, with participants allowed to submit\npull/merge requests at any point from October 1 - 31 in any timezone. However, there tends to be\nlarge spikes in submitted PR/MRs towards the start and end of the month as folks are reminded to\nget them in to count! Let's take a look at the most popular days during Hacktoberfest by accepted\nPR/MR creation this year:\n\n{{~ data.PRs.totalPRsByDay :item:i }}\n{{= i + 1 }}. {{= item[0] }}: {{= c(item[1]) }}\n  ({{= p(item[1] / data.PRs.totalAcceptedPRs) }} of all accepted PRs)\n{{~ }}\n\n\u003c!-- Clear for generated/prs_by_day_bar.png --\u003e\n\u003cp style=\"clear: both;\"\u003e\u003c/p\u003e\n\n## Diving in: Spam\n\nAfter the issues Hacktoberfest faced at the start of the 2020 event, spam was top of mind for our\nwhole team this year as we planned and launched Hacktoberfest {{= data.readme.year }}. We kept the\nrules the same as we'd landed on last year, with Hacktoberfest being an opt-in event for\nrepositories, and  our revised standards on quality contributions to make it easier for participants\nto understand what is expected of them when contributing to open source as part of Hacktoberfest.\n\n**Our efforts to reduce spam can be seen in our data, with only {{= c(data.PRs.totalSpamPRs) }}\n({{= p(data.PRs.totalSpamPRs / data.PRs.totalPRs) }}) pull/merge requests being flagged as spam by\nmaintainers (or identified as spam by our automated logic).** _(Of course, we can only report on\nwhat we see in our data here, and do acknowledge that folks may have received spam that wasn't\nflagged so won't be represented in our reporting)._\n\nWe also took a stronger stance on excluding repositories reported by the community that did not\nalign with our values, mostly repositories encouraging low effort contributions to allow folks to\nquickly win Hacktoberfest. Pull/merge requests to a repository that had been excluded from\nHacktoberfest, based on community reports, would not be counted for winning Hacktoberfest (but also\nwould not count against individual users in terms of disqualification).\n\n**Excluded repositories accounted for a much larger swathe of pull/merge requests during\nHacktoberfest, with {{= c(data.PRs.totalExcludedPRs) }}\n({{= p(data.PRs.totalExcludedPRs / data.PRs.totalPRs) }}) being discounted due to being submitted\nto an excluded repository.**\n\nIf we plot all pull/merge requests during Hacktoberfest by day, broken down by state, the impact\nthat excluded repositories had can be seen clearly, and also shows that there are significant spikes\nat the start and end of Hacktoberfest as folks trying to cheat the system tend to do so as\nHacktoberfest launches and its on their mind, or when they get our reminder email that Hacktoberfest\nis ending soon:\n\n![Stacked area plot of PR/MRs by created at day and state](generated/prs_by_state_stacked.png)\n\n\u003cimg src=\"generated/repos_reported_doughnut.png\" width=\"40%\" align=\"right\" alt=\"Doughnut diagram of reported repositories by review state\" /\u003e\n\nFor transparency, we can also take a look at the excluded repositories we processed for\nHacktoberfest {{= data.readme.year }}. A large part of this list was prior excluded repositories\nfrom previous Hacktoberfest years which were persisted across to this year. However, a form was\navailable on the site for members of our community to report repositories that they felt did not\nfollow our values, with automation in place to process these reports and exclude repositories that\nwere repeatedly reported, as well as reports being reviewed by our team.\n\nIn total, Hacktoberfest {{= data.readme.year }} had {{= c(data.Repos.totalReposExcluded) }}\nrepositories that were actively excluded,\n{{= p(data.Repos.totalReposExcluded / data.Repos.totalReposReported) }} of the total repositories\nreported. Only {{= c(data.Repos.totalReposPermitted) }} repositories were permitted after having\nbeen reported and subsequently reviewed by our team. Unfortunately,\n{{= c(data.Repos.totalReposUnreviewed) }}\n({{= p(data.Repos.totalReposUnreviewed / data.Repos.totalReposReported) }}) of the repositories that\nwere reported by the community were never reviewed by our team, and did not meet a threshold that\ntriggered any automation for exclusion.\n\n\u003c!-- Clear for generated/repos_reported_doughnut.png --\u003e\n\u003cp style=\"clear: both;\"\u003e\u003c/p\u003e\n\n## Wrapping up\n\nWell, that's all the stats I've generated from the Hacktoberfest {{= data.readme.year }} raw data --\nyou can find the raw output of the stats generation script in the\n[`generated/stats.txt`](generated/stats.txt) file, as well as all the graphics which are housed in\n[`generated`](generated) directory.\n\nIf there is anything more you'd like to see/know, please feel free to reach out and ask, I'll be\nmore than happy to generate it if possible.\n\nAll the scripts used to generate these stats \u0026 graphics are contained in this repository, in the\n[`src`](src) directory. I have some more information about this in the\n[CONTRIBUTING.md](CONTRIBUTING.md) file, including a schema for the input data, however, the\nHacktoberfest {{= data.readme.year }} raw data, much like previous years' data, isn't public.\n\nAuthor: [Matt Cowley](https://mattcowley.co.uk/) - If you notice any errors within this document\nplease let me know, and I will endeavour to correct them. 💙\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattipv4%2Fhacktoberfest-data","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattipv4%2Fhacktoberfest-data","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattipv4%2Fhacktoberfest-data/lists"}