Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thorn case study and case study components #138

Merged
merged 2 commits into from
Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"lodash": "^4.17.4",
"mdi-react": "^5.3.0",
"node-sass": "^4.9.4",
"parse-filepath": "^1.0.2",
"prismjs": "^1.14.0",
"react": "^16.5.2",
"react-bootstrap": "^1.0.0-beta.8",
Expand Down
2 changes: 1 addition & 1 deletion website/src/components/Jumbotron.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'

const COLORS = {
export const COLORS = {
dark: 'bg-black text-light',
purple: 'bg-purple text-light',
}
Expand Down
81 changes: 81 additions & 0 deletions website/src/components/content/CaseStudyPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react'
import { COLORS } from '../Jumbotron'

interface Props {
title: string
logo: string
heroImage?: React.ReactFragment
children: React.ReactNode
}

export const CaseStudyPage: React.FunctionComponent<Props> = ({
title,
logo,
heroImage,
children,
}) => (
<div className="">
<CaseStudyJumbotron className="mb-5" title={title} logo={logo}>
</CaseStudyJumbotron>
{children}
</div>
)

export const CaseStudyJumbotron: React.FunctionComponent<{
logo: string
title: string
className?: string
color?: keyof typeof COLORS
titleClassName?: string
children: React.ReactNode
}> = ({
logo,
title,
className = '',
color = 'dark',
titleClassName = 'display-3',
children,
}) => (
<div className={`jumbotron rounded-0 ${COLORS[color]} ${className}`}>
<div className="container text-center pt-6 pb-5">
<img className="case-studies__logo" src={logo}/>
<h1 className={titleClassName}>{title}</h1>
{children}
</div>
</div>
)

export const MediaQuote: React.FunctionComponent<{
image: string
quote: string
author: string
}> = ({
image,
quote,
author
}) => (
<div class="media case-studies__quote">
<img className="rounded-circle" src={image} alt={author} />
<blockquote class="blockquote">
<div class="container">
<p>{quote}</p>
<footer class="blockquote-footer">{author}</footer>
</div>
</blockquote>
</div>
)

export const InContentBlockquote: React.FunctionComponent<{
quote: string
author: string
}> = ({
quote,
author
}) => (
<blockquote class="blockquote case-studies__quote case-studies__quote--in-content">
<p>{quote}</p>
{author && (
<footer class="blockquote-footer">{author}</footer>
)}
</blockquote>
)
68 changes: 68 additions & 0 deletions website/src/css/pages/__case_studies.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.case-studies {
h2 {
font-size: 28px;
}

&__wrapper {
width: 66.667%;
margin: auto;
max-width: 740px; // Copied from medium.com
}

&__title {
&--rule {
margin: 25px 0;
}
}

&__logo {
margin: 0 0 2rem 0;
height: 3rem;
}

&__quote {
margin-bottom: 2rem 0 2rem 0;

.container {
margin: 2rem 0 0 2rem;
}

p {
text-indent: 0.4em;
font-weight: 700;
color: #212529;
font-size: 36px;
line-height: 1;
letter-spacing: -0.015em;

&:before {
text-indent: -0.4em;
content: "“";
position: absolute;
margin-left: -2px;
}

&:after {
content: "”";
margin-left: 2px;
}
}

footer {
margin-top: 2rem;
font-size: 18px;
font-weight: 400;
text-indent: -0.9rem;
}

&--in-content {
margin: 2rem 0;

p {
font-weight: 500;
font-size: 24px;
line-height: 1.3;
}
}
}
}
1 change: 1 addition & 0 deletions website/src/css/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ img.icon-inline,
@import 'pages/browser';
@import 'pages/blog';
@import 'pages/blog-post';
@import 'pages/_case_studies';
@import 'pages/content';
@import 'pages/index';
@import 'pages/jobs';
Expand Down
99 changes: 99 additions & 0 deletions website/src/pages/case-studies/we-are-thorn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import * as React from 'react'
import Helmet from 'react-helmet'
import { CaseStudyPage, InContentBlockquote, MediaQuote } from '../../components/content/CaseStudyPage'
import { ContentPage } from '../../components/content/ContentPage'
import { ContentSection } from '../../components/content/ContentSection'
import Layout from '../../components/Layout'
import { ContactPresalesSupportAction } from '../../css/components/actions/ContactPresalesSupportAction'
import { RequestDemoAction } from '../../css/components/actions/RequestDemoAction'
import { ViewDeveloperDocumentationAction } from '../../css/components/actions/ViewDeveloperDocumentationAction'

export default ((props: any) => (
<Layout location={props.location}>
<Helmet>
<title>Sourcegraph Case study - Thorn</title>
<meta name="twitter:title" content="How Thorn uses Sourcegraph to sunset legacy applications with zero downtime" />
<meta property="og:title" content="How Thorn uses Sourcegraph to sunset legacy applications with zero downtime" />
<meta
name="twitter:description"
content="Learn how Sourcegraph code search enabled Thorn to systematically sunset legacy systems, removing huge amounts of tech debt in the process."
/>
<meta
property="og:description"
content="Learn how Sourcegraph code search enabled Thorn to systematically sunset legacy systems, removing huge amounts of tech debt in the process."
/>
<meta
name="description"
content="Learn how Sourcegraph code search enabled Thorn to systematically sunset legacy systems, removing huge amounts of tech debt in the process."
/>
<link rel="icon" type="image/png" href="https://about.sourcegraph.com/favicon.png" />
</Helmet>

<CaseStudyPage
title="How Thorn uses Sourcegraph to sunset legacy applications with zero downtime."
logo="/case-studies/thorn-logo.png"
>
<ContentSection color="white" className="pt-5 pb-3">
<MediaQuote
image="/case-studies/jacob-gillespie-thorn-square.jpg"
quote="It was time-consuming for developers and reviewers to ensure that changes to legacy systems didn’t affect our production stability."
author="Thorn Software Engineer Jacob Gilesspie" />
</ContentSection>

<ContentSection color="white" className="col-md-6">
<h2>Thorn's mission</h2>

<p>Thorn builds technology to defend children from sexual abuse. Their work focuses on finding victims of child sex trafficking faster, and eliminating child sexual abuse from the internet.Thorn partners with tech companies, law enforcement, as well as other NGOs, to build products that provide the front lines with the latest technology to find the most vulnerable child victims faster.

</p>
<p>Thorn’s life changing work and not-for-profit status made it a simple decision to provide Sourcegraph’s enterprise features free of charge. For many children, Thorn plays a critical role in speeding up the time it takes for them to be identified and we’re proud to be supporting them with their mission.</p>

<h2 class="pt-6 pb-3">Sunsetting deprecated systems was previously costly and risked production stability</h2>
<p>As Thorn’s products evolved, it became difficult to trace the impact of code changes to core application components, as it was difficult to determine what code might rely on legacy architecture, risking instability and greatly increasing the demand on development and review.</p>

<InContentBlockquote quote="It was time-consuming for developers and reviewers to ensure that changes to legacy systems didn’t affect our production stability." />

<p>Over 9,000 officers in 38 countries rely on Thorn’s systems to identify child victims of sexual abuse. Any downtime of these services has a negative impact on Thorn’s ability to identify children globally.</p>

<h2 class="pt-6 pb-3">Existing tooling was not sufficient</h2>

<p>Tech debt, and the upkeep of legacy code was becoming increasingly problematic. Previous attempts, such as cloning all repositories locally and using grep to find references, were inadequate, especially when considering simultaneous development by multiple teams across many different projects, repositories, and branches. It was costly to determine if all the different microservices were properly in sync when removing legacy application code.</p>

<p>Sourcegraph’s multi-repository code search, was able to prove that no code referencing legacy systems exists organization-wide</p>

<p>Thorn Software Engineer Jacob Gillespie deployed Sourcegraph and synced Thorn’s entire list of repositories within minutes.</p>

<InContentBlockquote quote="With Sourcegraph, we could search over the contents of every repository, in any or all branches in seconds." />

<p>Sourcegraph code search gave Thorn the ability to find references to deprecated systems. But more importantly, it proved itself to be an invaluable new part of their code review process.</p>

<InContentBlockquote quote="In pull requests, team members would include links to Sourcegraph code search, in order to prove all references to a deprecated system had been removed. This gave the reviewer confidence that the code was safe to merge." />

<h2 class="pt-6 pb-3">As a result, deprecated systems were taken offline without downtime.</h2>
<p>Thorn’s developers could then systematically remove or modify deprecated systems, removing huge amounts of tech debt in the process. This benefited all areas of the architecture, including not only application code, but also build, deployment, logging, and monitoring systems—any tool that supported the deployment and uptime of the application.</p>

<p>Modern microservice architecture makes the application deprecation process more challenging than ever. </p>

<p>Sourcegraph’s code search enables developers and DevOps teams to find dead code, unused packages, and references to deprecated systems, organization wide across tens of thousands of repositories.</p>

<p class="pb-6">Being able to take advantage of industry leading solutions like Sourcegraph provides critical support to Thorn’s mission. Every start-up has to make choices about when to rebuild their systems and when to move forward accruing technical debt, Thorn is no different, but here at Sourcegraph, we’re proud that our tools could be used to make the Thorn team a little more successful, a little faster.</p>
</ContentSection>
</CaseStudyPage>
<ContentPage
title="Code search and navigation"
description="Code search helps you grok code so you can write better code more quickly. Sourcegraph's code search is used by elite software teams."
mainActions={
<div className="d-flex flex-column align-items-center">
<RequestDemoAction className="mt-3" />
<ContactPresalesSupportAction className="mt-3 text-light" />
<ViewDeveloperDocumentationAction
className="text-light mt-2"
url="https://docs.sourcegraph.com/#quickstart"
>
Documentation &amp; self-service install
</ViewDeveloperDocumentationAction>
</div>
}
></ContentPage>
</Layout>
)) as React.FunctionComponent<any>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/static/case-studies/thorn-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading