<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kylee Morgan</title>
    <description>The latest articles on DEV Community by Kylee Morgan (@morganintech).</description>
    <link>https://dev.to/morganintech</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2671352%2Fd2ae3a22-c380-45be-8d41-411707dc87da.png</url>
      <title>DEV Community: Kylee Morgan</title>
      <link>https://dev.to/morganintech</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/morganintech"/>
    <language>en</language>
    <item>
      <title>Expanding Software Engineering Teams for Social Impact Projects</title>
      <dc:creator>Kylee Morgan</dc:creator>
      <pubDate>Sun, 13 Sep 2026 21:47:31 +0000</pubDate>
      <link>https://dev.to/morganintech/expanding-software-engineering-teams-for-social-impact-projects-2jkg</link>
      <guid>https://dev.to/morganintech/expanding-software-engineering-teams-for-social-impact-projects-2jkg</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: Engineering Capacity Is a Bottleneck
&lt;/h2&gt;

&lt;p&gt;Hiring full-time engineers is expensive and competitive, especially on a nonprofit, mission-driven budget. Meanwhile, there's a large population of developers who want to contribute to meaningful projects without signing on for a full-time role. Open source is the mechanism that connects those two realities.&lt;/p&gt;

&lt;p&gt;This is how I doubled the engineering capacity for social impact tech organizations on GitHub by leveraging open-source to find quality contributors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Open Source Can Expand Your Engineering Team
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More contributors without proportional hiring.&lt;/strong&gt; An active open source project extends the engineering team with a contributor network. Internal engineers focus on high-priority work (architecture, product-direction, major features / migrations, security); external contributors take on dependnecy upgrades, maintenance, bugs, documentation, tests, and other well-scoped tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Attract mission-aligned engineers.&lt;/strong&gt; Open source makes your technical work visible before without ever posting a job listing. That builds a pipeline of people already invested in the mission, and increases speed of hiring.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Build technology others can reuse.&lt;/strong&gt; Social impact organizations frequently solve problems other organizations face too. Open sourcing those solutions lets the work benefit an entire ecosystem instead of staying locked inside one org.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhance code quality.&lt;/strong&gt; Open-source improves code quality through continuous peer review, radical transparency, and diverse global collaboration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Make Repository Discoverable
&lt;/h2&gt;

&lt;p&gt;None of this works if contributors can't find you. Contributors interested in social impact work tend to search in a few predictable places, so it's worth showing up in them deliberately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Topic tags&lt;/strong&gt;: Tag your repository with &lt;code&gt;social-good&lt;/code&gt;, &lt;code&gt;social-impact&lt;/code&gt;, &lt;code&gt;opensourceforgood&lt;/code&gt;, &lt;code&gt;sustainable-development-goals&lt;/code&gt; or &lt;code&gt;sdg&lt;/code&gt;, &lt;code&gt;digital-public-goods&lt;/code&gt; or &lt;code&gt;dpg&lt;/code&gt;, and &lt;code&gt;non-profit&lt;/code&gt;. These are the exact terms contributors use to search GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Digital Public Goods Registry&lt;/strong&gt;: If your project meets the &lt;a href="https://digitalpublicgoods.net/registry/" rel="noopener noreferrer"&gt;Digital Public Good Standard&lt;/a&gt; — open-source codebase, transparent ownership, data privacy compliance, alignment with the UN's Sustainable Development Goals — registering puts you in front of an audience actively looking for projects exactly like yours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub collections&lt;/strong&gt;: Get listed in relevant &lt;a href="https://github.com/collections/social-impact" rel="noopener noreferrer"&gt;GitHub collections&lt;/a&gt;, which group repositories by shared theme for easy browsing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good first issue lists&lt;/strong&gt;: Submit approachable issues to programs like &lt;a href="https://forgoodfirstissue.github.com/" rel="noopener noreferrer"&gt;GitHub's Social Impact "Good First Issue" list&lt;/a&gt;, which exists specifically to route new contributors to projects like yours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anchor to an SDG&lt;/strong&gt;: Framing your project against a specific &lt;a href="https://sdgs.un.org/goals" rel="noopener noreferrer"&gt;Sustainable Development Goal&lt;/a&gt; gives potential contributors an immediate answer to "why does this matter" before they read a line of code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Make Repository Contributor-Friendly
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start by making the project contributor-friendly.&lt;/strong&gt; A public repository alone doesn't create a community. Make it easy for someone with zero context on your organization to get oriented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;README&lt;/strong&gt;: What does this project do, why does it matter, and do you set up it up locally?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CONTRIBUTING.md&lt;/strong&gt;: What is the standardization framework for assigning, reviewing, and accepting contributions?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue + Pull Request templates&lt;/strong&gt;: What needs to be done before opening an issue or pull request?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code of Conduct&lt;/strong&gt;: What kind of community are you building?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check &lt;a href="https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/accessing-a-projects-community-profile?versionId=free-pro-team%40latest&amp;amp;productId=discussions&amp;amp;restPage=managing-discussions-for-your-community%2Cviewing-insights-for-your-discussions" rel="noopener noreferrer"&gt;GitHub's Community Insights&lt;/a&gt; in your repository settings to verify all requirements (including those listed above).&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Issues
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Turn your backlog into contribution opportunities.&lt;/strong&gt; Not every engineering task needs to be handled internally. Use GitHub Issues to identify externally contributable work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation improvements&lt;/li&gt;
&lt;li&gt;Bug fixes&lt;/li&gt;
&lt;li&gt;Tests&lt;/li&gt;
&lt;li&gt;Accessibility improvements&lt;/li&gt;
&lt;li&gt;Small features&lt;/li&gt;
&lt;li&gt;Developer tooling&lt;/li&gt;
&lt;li&gt;Dependency updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Label issues clearly: &lt;code&gt;good first issue&lt;/code&gt;, &lt;code&gt;help wanted&lt;/code&gt;, &lt;code&gt;documentation&lt;/code&gt;, plus desired tech stacks or skills, so contributors can self-select into appropriate work instead of guessing. Issue labels should be standardized, such &lt;a href="https://medium.com/@dave_lunny/sane-github-labels-c5d2e6004b63" rel="noopener noreferrer"&gt;Sane GitHub Labels by David Lunny&lt;/a&gt; methodology. &lt;/p&gt;

&lt;p&gt;Track progress and activity metrics with GitHub's built-in tools: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/issues/using-labels-and-milestones-to-track-work/about-milestones" rel="noopener noreferrer"&gt;GitHub Milestones&lt;/a&gt; and &lt;a href="https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects" rel="noopener noreferrer"&gt;GitHub Project Boards&lt;/a&gt; to track issue completion.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/repositories/viewing-activity-and-data-for-your-repository/viewing-a-projects-contributors" rel="noopener noreferrer"&gt;GitHub Contributor Insights&lt;/a&gt; to track contributor activity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your Open Source Collaboration Framework
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Finally, treat contributors like part of the team.&lt;/strong&gt; Open source contribution shouldn't feel like throwing code over a wall. There should be a lightweight system of reviewing pull requests, answering questions, giving feedback, recognizing contributions, and communicating project priorities.&lt;/p&gt;

&lt;h3&gt;
  
  
  !important Security
&lt;/h3&gt;

&lt;p&gt;While GitHub provides many built-in tools like dependabot, internal engineers must have a system for ensuring public contributions are safe. I wrote blog post about this &lt;a href="https://www.communaltech.com/articles/programming_01.mdx" rel="noopener noreferrer"&gt;here&lt;/a&gt;. In general, reviewers should not run untrusted code without thorough review and precautions, security scans, and following best practices. Additionally, if participating in events like Hacktoberfest, maintainers need to a system prepared for handling mass, low-effort contributions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing: Start Small
&lt;/h2&gt;

&lt;p&gt;You don't need hundreds of contributors or to waste engineer's time with outreach and reviews to see the benefit. Open source enables engineers to do more meaningful work, connect, use their skills for issues they care about, and leads to higher code quality.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>techforgood</category>
      <category>github</category>
    </item>
    <item>
      <title>Securely Merging Pull Requests from Public Contributors</title>
      <dc:creator>Kylee Morgan</dc:creator>
      <pubDate>Sun, 13 Sep 2026 21:44:56 +0000</pubDate>
      <link>https://dev.to/morganintech/securely-merging-pull-requests-from-public-contributors-3kl5</link>
      <guid>https://dev.to/morganintech/securely-merging-pull-requests-from-public-contributors-3kl5</guid>
      <description>&lt;h2&gt;
  
  
  Intro: &lt;strong&gt;Maintainers Caught at a Fork 🍴&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;How can maintainers safely test forked PRs without exposing sensitive data to potentially untrusted code? This article explores how on forked pull requests authored by public code contributors, with no elevated permissions from repository / organization roles, can be securely merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Terminology:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event Trigger&lt;/strong&gt;: Event that initiates a workflow in GitHub Actions (like push, pull_request, and workflow_run).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context (in GitHub Actions)&lt;/strong&gt;: The environment of where the workflow run, determined by the event trigger, repository, and branch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;actions/checkout&lt;/strong&gt;: A GitHub Action that checks out a repository at a specific commit or ref so a workflow can access the code in the workflow's context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pull_request&lt;/strong&gt;: An event trigger that runs your workflow when activity on a pull request in the workflow's repository occurs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Head&lt;/strong&gt; (&lt;strong&gt;source&lt;/strong&gt;): refers to the branch / repository containing the proposed code changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base&lt;/strong&gt; (&lt;strong&gt;target&lt;/strong&gt;): refers to the branch / repository where proposed code changes are being merged into.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Workflow Permissions - Internal vs. Forked Pull Requests:
&lt;/h3&gt;

&lt;p&gt;When a workflow includes the &lt;code&gt;actions/checkout&lt;/code&gt; action, it uses the &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; to authenticate and fetch the repository at a specific commit or ref, placing the files into the &lt;code&gt;$GITHUB_WORKSPACE&lt;/code&gt; directory, the workflow's context, so subsequent steps can access them. By default, workflows triggered by &lt;code&gt;pull_request&lt;/code&gt; run &lt;code&gt;actions/checkout&lt;/code&gt; in the context of the pull request’s head commit. But for forked pull requests, the &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; is read-only and secrets are unavailable. &lt;a href="https://youtu.be/Ww5gjAm-2GY?t=890" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub intentionally configures this as a security measure&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This design ensures untrusted code does not access repository secrets, meaning secret-dependent workflows fail on forks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety:
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Risks of Granting Secrets Access on Untrusted Code:
&lt;/h3&gt;

&lt;p&gt;While security mitigations minimize risk, there is no foolproof way to securely allow secrets access on untrusted forked PRs. From injecting malicious code to exploiting race conditions, I invite readers to view this &lt;a href="https://github.com/TupleType/awesome-cicd-attacks" rel="noopener noreferrer"&gt;&lt;strong&gt;repository&lt;/strong&gt;&lt;/a&gt; for a list of all the things that can go wrong. Ultimately, all public code contributions need to be treated as &lt;strong&gt;untrusted code:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“&lt;em&gt;Any automated processing of PRs from an external fork is potentially dangerous and such PRs should be treated like untrusted input.&lt;/em&gt;” - Jaroslav Lobačevski, GitHub, writes in &lt;a href="https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/" rel="noopener noreferrer"&gt;&lt;strong&gt;Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So here are 3 solutions, ranging from least to most secure, for running secret-dependent workflows, such as tests, on untrusted forks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Solution 1 - Dangerous Use of pull_request_target:
&lt;/h3&gt;

&lt;p&gt;Introduced in &lt;a href="https://github.blog/news-insights/product-news/github-actions-improvements-for-fork-and-pull-request-workflows/" rel="noopener noreferrer"&gt;&lt;strong&gt;2021&lt;/strong&gt;&lt;/a&gt;, GitHub provides the &lt;code&gt;pull_request_target&lt;/code&gt; event to elevate the &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; permissions to read/write on forked pull requests. By default, this sets the context as the base repository, rather than the fork, allowing metadata-only (no secrets) workflows to run, such as automated labels, comments, project board updates, etc. within a trusted context.&lt;/p&gt;

&lt;p&gt;Unlike &lt;code&gt;pull_request&lt;/code&gt;, secrets-dependent workflows run successfully on forks, but not in the context of the proposed code changes; misleading unaware developers with false test results. To run secrets-dependent workflows on proposed code changes in untrusted forks, the fork’s PR head SHA must be explicitly set with &lt;code&gt;actions/checkout&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout PR branch&lt;/span&gt;
&lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
&lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.head.ref }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is dangerous on it's own. The primary use case for &lt;code&gt;pull_request_target&lt;/code&gt; is non-invasive, maintainer tasks on forks, not running or building untrusted code. Any developer using &lt;code&gt;pull_request_target&lt;/code&gt; for any reason should carefully read the warnings and precautions here: &lt;a href="https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request_target" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Docs: pull_request_target.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution 2 - The workflow_run Prescan:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.blog/news-insights/product-news/github-actions-improvements-for-fork-and-pull-request-workflows/#improvements-for-public-repository-forks" rel="noopener noreferrer"&gt;&lt;strong&gt;Also introduced in 2021&lt;/strong&gt;&lt;/a&gt;, the &lt;code&gt;workflow_run&lt;/code&gt; event enables chained workflows and elevates permissions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The workflow started by the workflow_run event is able to access secrets and write tokens, even if the previous workflow was not.” - &lt;a href="https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Official Documentation&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The trick is to create 2 workflows; first for static analysis of the untrusted code, the second for granting secrets access. This helps minimize the risk of exposing secrets to untrusted code by isolating read and write permission jobs.&lt;/p&gt;

&lt;p&gt;The prescan is triggered by &lt;code&gt;pull_request&lt;/code&gt;, setting the untrusted code in it's context and no secrets access. Upon successful completion of the prescan, the second workflow is triggered by &lt;code&gt;workflow_run&lt;/code&gt;, granting secrets access to perform secret-dependent workflow runs on proposed code changes in forks, such as tests.&lt;/p&gt;

&lt;p&gt;The prescan workflow should fail if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Author is verified as untrusted with &lt;code&gt;if&lt;/code&gt; comparisons. For example, if the head (source) respository's full name (owner-name/repo-name and always unique) matches trusted authors or by &lt;a href="https://michaelheap.com/github-actions-check-permission/" rel="noopener noreferrer"&gt;&lt;strong&gt;author permissions&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Changes made to sensitive files like &lt;code&gt;.github/workflows/*&lt;/code&gt;, &lt;code&gt;.gitignore&lt;/code&gt;, scripts.&lt;/li&gt;
&lt;li&gt;Fail on static analysis via &lt;a href="https://github.blog/security/application-security/how-to-secure-your-github-actions-workflows-with-codeql/" rel="noopener noreferrer"&gt;&lt;strong&gt;CodeQL&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Solution 3 - Use Isolated, Disposable Environments:
&lt;/h3&gt;

&lt;p&gt;In my opinion, this is the best solution is simply running tests locally by cloning into an isolated, disposable environment after successful completion of a prescan workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Require contributors to obtain their own test secrets (if accessible), run tests locally, and share screenshot of results in the PR template. Clearly document in README and CONTRIBUTING file. This does not negate the need to run your own tests.&lt;/li&gt;
&lt;li&gt;Always require maintainer approval before workflow runs on forks.&lt;/li&gt;
&lt;li&gt;Never expose secrets directly in a &lt;code&gt;pull_request_target&lt;/code&gt; workflow checking out PR code. Use dummy secrets with limited permissions and monitor them regularly.&lt;/li&gt;
&lt;li&gt;Never use variable untrusted data in prescan workflow logic, such as &lt;code&gt;github.event.pull_request.title&lt;/code&gt; which users can alter during workflow runs.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#good-practices-for-mitigating-script-injection-attacks" rel="noopener noreferrer"&gt;&lt;strong&gt;Prevent script injection in run steps and prefer GitHub Actions over inline scripts.&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions" rel="noopener noreferrer"&gt;&lt;strong&gt;Pin marketplace Actions versions with commit SHAs&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Stay updated on security hardening for GitHub Actions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Further Reading:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.blog/news-insights/product-news/github-actions-improvements-for-fork-and-pull-request-workflows/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Blog: Actions Improvements for Fork and Pull Request Workflows&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/security/supply-chain-security/four-tips-to-keep-your-github-actions-workflows-secure/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Blog: Four Tips to Keep You GitHub Actions Workflows Secure&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/security/application-security/how-to-secure-your-github-actions-workflows-with-codeql/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Blog: How to Secure Your GitHub Actions Workflows with CodeQL&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/security/application-security/security-best-practices-for-authors-of-github-actions/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Blog: Security Best Practices for Authors of GitHub Actions&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Docs: Actions Security Hardening for GitHub Actions&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull-request-events-for-forked-repositories" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Docs: Pull Request Events for Forked Repositories&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflows-in-forked-repositories" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Docs: Workflows in Forked Repositories&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Security Lab: Preventing Pwn Requests&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wellarchitected.github.com/library/application-security/recommendations/actions-security/" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Well-Architected Docs: Securing GitHub Actions Workflows Guide&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://michaelheap.com/access-secrets-from-forks/" rel="noopener noreferrer"&gt;&lt;strong&gt;Michael Heap Blog: How to Safely Access Secrets from Forks&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Increasing Global Developer Coverage for Open-Source Organizations: with Docker and PostgreSQL</title>
      <dc:creator>Kylee Morgan</dc:creator>
      <pubDate>Mon, 20 Jan 2025 18:07:38 +0000</pubDate>
      <link>https://dev.to/morganintech/increasing-global-developer-coverage-for-open-source-organizations-with-docker-and-postgresql-3pgd</link>
      <guid>https://dev.to/morganintech/increasing-global-developer-coverage-for-open-source-organizations-with-docker-and-postgresql-3pgd</guid>
      <description>&lt;p&gt;Open-source projects thrive on community contributions, but one of the biggest barriers for new contributors is setting up a local development environment. With varying tech stacks, computer usage limits, and dependency overhead, how can open-source projects provide a one-size-fits-all setup?&lt;/p&gt;

&lt;p&gt;Recently, I addressed these challenges for a free, open-source, privacy-first therapy application called Bloom. After containerizing the application with Docker, contributors were still required to host PostgreSQL data locally. While this approach was practical for backend development, it posed challenges for frontend contributors, as PostgreSQL hosting was necessary to run integration tests. To attract talented contributors, it became essential to minimize dependency overhead and align development requirements with the needs of developers. Additionally, offering flexible solutions to accommodate diverse computing capabilities was prioritized to help expand global developer accessibility.&lt;/p&gt;

&lt;p&gt;Here’s how it worked, and the impact it made 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Lowering the Barrier to Entry
&lt;/h2&gt;

&lt;p&gt;For developers interested in contributing to Bloom, getting the app running locally was often the first hurdle. Depending on their environment, contributors had to grapple with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing and configuring PostgreSQL.&lt;/li&gt;
&lt;li&gt;Manually populated their database with test data.&lt;/li&gt;
&lt;li&gt;Managing dependencies that conflicted with their existing stack.&lt;/li&gt;
&lt;li&gt;Adapting to Docker’s or PostgreSQL’s learning curve if they weren’t already familiar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These issues would deter new contributors, especially those with limited system resources or time.&lt;/p&gt;

&lt;p&gt;The Solution: Offering Flexible Setup Options 🌐&lt;br&gt;
To make contributing more accessible, I configured three distinct, cross-compatible setup paths with clear documentation for seamlessly implementing each:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Manual Hosting with PostgreSQL:&lt;/strong&gt;&lt;br&gt;
For developers who prefer working directly with PostgreSQL on their local machine, this option allows them to host the database manually. Additionally, this lowered computer resource usage, as Docker has a high overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Connecting a Locally Hosted PostgreSQL Database to Docker:&lt;/strong&gt;&lt;br&gt;
Some contributors might already have PostgreSQL installed and want to keep it separate from Docker. This option lets them connect their locally hosted database to the Dockerized application, bridging the gap between containerized and non-containerized setups. This also provided a compromise for computer usage and dependency overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Running the App Entirely in Docker (with Persistent Data):&lt;/strong&gt;&lt;br&gt;
For devs who prefer a fully containerized development environment, they can now the backend and database in Docker (my personal favorite method). This approach minimizes dependency conflicts and leverages Docker-specific PostgreSQL tools. To ensure persistent data storage, similar to a locally hosted PostgreSQL database, I configured &lt;a href="https://docs.docker.com/engine/storage/volumes/" rel="noopener noreferrer"&gt;Docker volumes&lt;/a&gt;. With Docker volumes, this enabled both staff developers and contributors to fully containerize the application without needing to re-populate the database with each new container. Additionally, this streamlined my pull request workflow as a maintainer, as I no longer needed to manually populate the database from a forked branch when reviewing complex pull requests locally. Of course, there are caveats to this method, forked pull request tests run on my machine using Docker volumes can alter my local database, but I quickly realized I could navigate this using &lt;a href="https://github.com/tmux/tmux/wiki" rel="noopener noreferrer"&gt;tmux multiplexers&lt;/a&gt; or &lt;a href="https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/" rel="noopener noreferrer"&gt;&lt;code&gt;docker-compose.override.yml&lt;/code&gt; files&lt;/a&gt; (that is for a future blog post).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why These Options Matter?
&lt;/h2&gt;

&lt;p&gt;This flexible setup benefits staff and community developers alike by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Catering to diverse preferences:&lt;/strong&gt; Whether a developer prefers Docker or manual PostgreSQL configurations, they can choose the setup that works best for them. ✔️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accommodating resource limitations:&lt;/strong&gt; Developers with lower-powered machines or network limitations can manually use PostgreSQL, while those with more resources can opt for containerization. ✔️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reducing dependency conflicts:&lt;/strong&gt; Each option minimizes the risk of version mismatches or conflicts with pre-installed tools. ✔️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implements consistency:&lt;/strong&gt; Regardless of the set-up developers opt for, the code remains consistent, and data is persistent. ✔️&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Results: A More Inclusive Developer Community
&lt;/h2&gt;

&lt;p&gt;By lowering the barrier to entry, these setup options helped attract more contributors to Bloom and streamlined the workflow for maintainers. As an open-source tech organization focused on advocating for positive social impact, utilizing the most of limited resources is paramount for this project. With this new set-up, developers can start working on the app faster and with less frustration, fostering a more inclusive and engaged developer community. So far, contributor troubleshooting inquiries have been reduced, but this is only the beginning! Ultimately, this was an excellent learning opportunity for me as a developer advocate, and for contributors exploring Docker and PostgreSQL configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways for Other Open-Source Projects
&lt;/h2&gt;

&lt;p&gt;If you’re looking to improve community outreach for your open-source project, consider implementing flexible setup options like these. Providing contributors with choices tailored to their preferences and constraints, while maintaining consistency for staff developers, can make a significant difference in empowering contributors to engage.&lt;/p&gt;

&lt;p&gt;When evaluating the onboarding flow for open-source applications, here are questions I like to ask myself:&lt;/p&gt;

&lt;p&gt;Is this set-up causing contributors to drop of, and if so, where? &lt;br&gt;
Can the gaps in the onboarding flow be resolved?&lt;br&gt;
How can we provide flexible dev environment set-up options to enhance developer reach?&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for reading this far! 🏆
&lt;/h2&gt;

&lt;p&gt;If this post interested you, let's connect! I am always looking to collaborate with passionate technologists. Schedule a chat with me today: &lt;a href="https://calendly.com/communaltech/coffee-chat-15-30min" rel="noopener noreferrer"&gt;https://calendly.com/communaltech/coffee-chat-15-30min&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for more, if you enjoyed this post, I invite you to follow my work on GitHub: &lt;a href="https://github.com/kyleecodes" rel="noopener noreferrer"&gt;https://github.com/kyleecodes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>docker</category>
      <category>postgres</category>
      <category>database</category>
    </item>
  </channel>
</rss>
