POPULARITY
2024 年 3 月に公開された、JetBrains 社の TeamCitry の脆弱性の悪用を試みるエクスプロイトコードが公開されています。
SANS Internet Stormcenter Daily Network/Cyber Security and Information Security Stormcast
From JavaScript to AsyncRAT https://isc.sans.edu/diary/From%20JavaScript%20to%20AsyncRAT/30788 TeamCity Patches https://www.jetbrains.com/privacy-security/issues-fixed/?product=TeamCity&version=2024.03 Okta Verify for Windows Auto-update Arbitrary Code Execution CVE-2024-0980 https://trust.okta.com/security-advisories/okta-verify-windows-auto-update-arbitrary-code-execution-cve-2024-0980/ Google Zero Day Report https://storage.googleapis.com/gweb-uniblog-publish-prod/documents/Year_in_Review_of_ZeroDays.pdf
SANS Internet Stormcenter Daily Network/Cyber Security and Information Security Stormcast
From JavaScript to AsyncRAT https://isc.sans.edu/diary/From%20JavaScript%20to%20AsyncRAT/30788 TeamCity Patches https://www.jetbrains.com/privacy-security/issues-fixed/?product=TeamCity&version=2024.03 Okta Verify for Windows Auto-update Arbitrary Code Execution CVE-2024-0980 https://trust.okta.com/security-advisories/okta-verify-windows-auto-update-arbitrary-code-execution-cve-2024-0980/ Google Zero Day Report https://storage.googleapis.com/gweb-uniblog-publish-prod/documents/Year_in_Review_of_ZeroDays.pdf
Sponsor by SEC Playground --- Support this podcast: https://podcasters.spotify.com/pod/show/chillchillsecurity/support
A majority of internet traffic now originates from APIs, and cybercriminals are taking advantage. Increasingly, APIs are used as a common attack vector because they're a direct pathway to access sensitive data. In this discussion, Lebin Cheng shares what API attack trends Imperva, a Thales Company has observed over the past year, and what steps organizations can take to protect their APIs. This segment is sponsored by Imperva. Visit https://www.securityweekly.com/imperva to learn more about them! The trivial tweaks to bypass authentication in TeamCity, ArtPrompt attacks use ASCII art against LLMs, annoying developers with low quality vuln reports, removing dependencies as part of secure by design, removing overhead with secure by design, and more! Visit https://www.securityweekly.com/asw for all the latest episodes! Show Notes: https://securityweekly.com/asw-276
The trivial tweaks to bypass authentication in TeamCity, ArtPrompt attacks use ASCII art against LLMs, annoying developers with low quality vuln reports, removing dependencies as part of secure by design, removing overhead with secure by design, and more! Show Notes: https://securityweekly.com/asw-276
A majority of internet traffic now originates from APIs, and cybercriminals are taking advantage. Increasingly, APIs are used as a common attack vector because they're a direct pathway to access sensitive data. In this discussion, Lebin Cheng shares what API attack trends Imperva, a Thales Company has observed over the past year, and what steps organizations can take to protect their APIs. This segment is sponsored by Imperva. Visit https://www.securityweekly.com/imperva to learn more about them! The trivial tweaks to bypass authentication in TeamCity, ArtPrompt attacks use ASCII art against LLMs, annoying developers with low quality vuln reports, removing dependencies as part of secure by design, removing overhead with secure by design, and more! Visit https://www.securityweekly.com/asw for all the latest episodes! Show Notes: https://securityweekly.com/asw-276
The trivial tweaks to bypass authentication in TeamCity, ArtPrompt attacks use ASCII art against LLMs, annoying developers with low quality vuln reports, removing dependencies as part of secure by design, removing overhead with secure by design, and more! Show Notes: https://securityweekly.com/asw-276
Is the ALPHV gang pulling up a twenty two million dollar rug? Meta platforms are experiencing outages. Ukraine claims a cyberattack on the Russian Ministry of Defense. Malicious phishers hope to hook hashes. TeamCity users are warned of critical vulnerabilities. The Discord leaker pleads guilty. AmEx suffers a third-party data breach. Amazon is flooded with fake copycat publications. Our guest is Deputy Assistant Director Cynthia Kaiser from the FBI Cyber Division to discuss Volt Typhoon. And, Dude, she is just not that into you. Remember to leave us a 5-star rating and review in your favorite podcast app. Miss an episode? Sign-up for our daily intelligence roundup, Daily Briefing, and you'll never miss a beat. And be sure to follow CyberWire Daily on LinkedIn. CyberWire Guest Guest Deputy Assistant Director Cynthia Kaiser from the FBI Cyber Division joins us to discuss Volt Typhoon. Selected Reading Hackers Behind the Change Healthcare Ransomware Attack Just Received a $22 Million Payment (WIRED) Ukraine claims it hacked Russian Ministry of Defense servers (Bleeping Computer) Hundreds of orgs targeted with emails aimed at stealing NTLM authentication hashes (Help Net Security) TeamCity Users Urged to Patch Critical Vulnerabilities (Infosecurity Magazine) Pentagon leak defendant Jack Teixeira pleads guilty, faces years in prison (Reuters) American Express credit cards exposed in third-party data breach (Bleeping Computer) Tech writer Kara Swisher has a new book. Enter the AI-generated scams. (Bleeping Computer) Retired Army officer charged with sharing classified information about Ukraine on foreign dating site (CBS News) Share your feedback. We want to ensure that you are getting the most out of the podcast. Please take a few minutes to share your thoughts with us by completing our brief listener survey as we continually work to improve the show. Want to hear your company in the show? You too can reach the most influential leaders and operators in the industry. Here's our media kit. Contact us at cyberwire@n2k.com to request more info. The CyberWire is a production of N2K Networks, your source for strategic workforce intelligence. © 2023 N2K Networks, Inc.
In today's podcast we cover four crucial cyber and technology topics, including: 1. Senegal shuts down mobile Internet access 2. TeamCity servers vulnerable to remote access via latest flaw 3. French healthcare data exposed for tens of thousands due to phish 4. Researchers reveal Chinese effort to spy on Dutch via cyber I'd love feedback, feel free to send your comments and feedback to | cyberandtechwithmike@gmail.com
An airhacks.fm conversation with Anton Arhipov (@antonarhipov) about: playing sports games on Pentium 233 MHz the 2014 JavaOne Rockstar awards about NetBeans, Eclipse, and IntelliJ., enjoying sports games and destroying joysticks, practicing competitive swimming, swim training, starting to program in Turbo Pascal at Maelardalen University, ship simulation with Java for Vasa Museum, joining a company which maintains RefactorIT, working with Java EE and WebLogic and JRockit, joining ZeroturnAround and working on JRebel, Rebel and LiveRebel, working on a profiler, JetBrain's MPS, DevRel for TeamCity, AppCode features are appearing in fleet, Fleet is built on common UI principles, the rendering engine Skia, Kotlin and Jetpack Compose, Circles by Anton Anton Arhipov on twitter: @antonarhipov
This episode reports on the growth of the KV-botnet, the discovery of another unprotected database on the internet, and more
Maarten loves building web and cloud apps. His main interests are in .NET web technologies, C#, and application performance. He is Developer Advocate at JetBrains and created SpeakerTravel, a tool to help conference organizers. Maarten is a frequent speaker at various national and international events. In his free time, he brews his own beer. Topics of Discussion: [4:34] The mindset difference between developing software applications for everyday use versus developer tools, and how it affects the programming process. [5:40] What is JetBrains, and why should .NET devs care? [6:44] IDE stands for integrated development environments. [9:01] JetBrains announcing Rider. [10:31] Essential software development patterns for desktop applications. [13:35] What does the code generally look like? Is it .NET events? Is it observer pattern? [15:54] Maarten talks about the approach of creating general-purpose business applications with modular components, making development and maintenance more efficient. [18:35] TeamCity, a continuous integration (CI) server used internally and for building products. [19:50] The concept of a safe merge. [21:11] JetBrains Toolbox. [21:53] How Maarten compartmentalizes tests. [24:44] Static analysis tools for code quality and customization. [27:38] Duplicate code identifier. [30:41] VS Code. [32:13] What are some interesting things to look out for in the future? Mentioned in this Episode: Clear Measure Way Architect Forum Software Engineer Forum Programming with Palermo — New Video Podcast! Email us at programming@palermo.net. Clear Measure, Inc. (Sponsor) .NET DevOps for Azure: A Developer's Guide to DevOps Architecture the Right Way, by Jeffrey Palermo — Available on Amazon! Jeffrey Palermo's Twitter — Follow to stay informed about future events! Maarten's Blog Rider Resharper Building a .NET IDE with JetBrains Rider NDepend Visual Studio for Mac Retirement Announcement .NET Annotated Monthly — Sept 2023 Want to Learn More? Visit AzureDevOps.Show for show notes and additional episodes.
A short podcast updating listeners on the security news of the last few days, as prepared by Catalin Cimpanu and read by Kaitlyn Sawrey. You can find the newsletter version of this podcast here.
In this week's Source Code podcast, we hear from Caitlin Condon with Rapid7 about a critical flaw in TeamCity, a continuous integration and continuous deployment tool. Also this week we discuss a recent FBI private industry notification about changing ransomware tactics, and flaws in the WS_FTP file transfer software from Progress Software.
Will dons the game developer hat again this week for a deep dive into how a game gets built. No, not the coding and design and art and all that -- we mean how a game gets literally built into a package that you can run on your PC or console, with some in-depth chat about everything from build servers to source and version control of both code and binary assets, pre-baked lighting, creating automated nightlies of your game, partying in TeamCity, and more.Support the Pod! Contribute to the Tech Pod Patreon and get access to our booming Discord, your name in the credits, and other great benefits! You can support the show at: https://patreon.com/techpod
Getting your foot in the door at the City of Madison can look different for so many people, with different backgrounds, apprenticeships, hourly positions, seasonal positions, part time positions, internships and training programs. In the past few years, we have been building on some key positions that are developing our workforce, and our #TeamCity. City of Madison Engineering Division Public Information Officer Hannah Mohelnitzky hosts Engineering Division Facilitites Coordinator Stephen King and Fleet Services Superintendent Mahanth Joishy to talk about two successful programs, and one new program anyone trying to work for the City of Madison should know about: GreenPower, Fleet Apprenticeship Program, MI-TE Program. Thinking about applying? Listen to this 20-minute episode to know what you can expect! https://media.cityofmadison.com/Mediasite/Play/bef223c2536d420fa3f3fff1bb5b41f81d
Marco Rossignoli is a Dev at Microsoft on the .NET Test Platform and Code coverage team. He's also the co-maintainer of the Coverlet Collector NuGet package, which has over 100M downloads. Topics of Discussion: [1:15] Jeffrey talks about the architect forums he's hosting and facilitating in 2023. You can register here. [2:53] Marco talks about how he got into code coverage. [6:44] Why is code coverage even useful to measure? [12:40] How does Coverlet work and how is it different from the old ones? How do you run it? [20:30] Is there any difference in how it works between Azure Pipelines or GitHub Actions or TeamCity? [21:40] With multiple test suites running, how does Coverlet support pulling all the results together so that you get the one number of code coverage? [23:40] Report generator merges all of the reports. [25:16] What exactly is Cobertura? [26:02] Marco shares why he is excited about Coverlet and the many opportunities it gives us in the future. Mentioned in this Episode: Architect Tips — New video podcast! Azure DevOps Clear Measure (Sponsor) .NET DevOps for Azure: A Developer's Guide to DevOps Architecture the Right Way, by Jeffrey Palermo — Available on Amazon! Jeffrey Palermo's YouTube Jeffrey Palermo's Twitter — Follow to stay informed about future events! Programming with Palermo programming@palermo.network NuGet Gallery GitHub Coverlet Coverage Marco Rossignoli .Net Coverage Code Want to Learn More? Visit AzureDevOps.Show for show notes and additional episodes.
About RobRob Zuber is a 20-year veteran of software startups; a four-time founder, three-time CTO. Since joining CircleCI, Rob has seen the company through its Series B, Series C, and Series D funding and delivered on product innovation at scale. Rob leads a team of 150+ engineers who are distributed around the globe.Prior to CircleCI, Rob was the CTO and Co-founder of Distiller, a continuous integration and deployment platform for mobile applications acquired by CircleCI in 2014. Before that, he cofounded Copious an online social marketplace. Rob was the CTO and Co-founder of Yoohoot, a technology company that enabled local businesses to connect with nearby consumers, which was acquired by Appconomy in 2011.Links: Twitter: @z00b LinkedIn URL: https://www.linkedin.com/in/robzuber/ Personal site: https://www.crunchbase.com/person/rob-zuber#section-overview Company site: www.circleci.com TranscriptAnnouncer: Hello, and welcome to Screaming in the Cloud with your host cloud economist, Corey Quinn. This weekly show features conversations with people doing interesting work in the world of cloud, thoughtful commentary on the state of the technical world and ridiculous titles for which Corey refuses to apologize. This is Screaming in the Cloud.Corey: If you asked me to rank which cloud provider has the best developer experience, I'd be hard-pressed to choose a platform that isn't Google Cloud. Their developer experience is unparalleled and, in the early stages of building something great, that translates directly into velocity. Try it yourself with the Google for Startups Cloud Program over at cloud.google.com/startup. It'll give you up to $100k a year for each of the first two years in Google Cloud credits for companies that range from bootstrapped all the way on up to Series A. Go build something, and then tell me about it. My thanks to Google Cloud for sponsoring this ridiculous podcast.Corey: This episode is brought to us by our friends at Pinecone. They believe that all anyone really wants is to be understood, and that includes your users. AI models combined with the Pinecone vector database let your applications understand and act on what your users want… without making them spell it out. Make your search application find results by meaning instead of just keywords, your personalization system make picks based on relevance instead of just tags, and your security applications match threats by resemblance instead of just regular expressions. Pinecone provides the cloud infrastructure that makes this easy, fast, and scalable. Thanks to my friends at Pinecone for sponsoring this episode. Visit Pinecone.io to understand more.Corey: Welcome to Screaming in the Cloud. I'm Corey Quinn. I'm joined this week by Rob Zuber, CTO of CircleCI. Rob, welcome to the show.Rob: Thanks. Thanks for having me. It's great to be here.Corey: It really is, isn't it? So you've been doing the CTO dance, for lack of a better term, at CircleCI for about five, six years now at this point?Rob: Yeah, that's right. I joined five and a half years ago. I actually came in through an acquisition. We were building a CI/CD platform for mobile, iOS specifically, and there were just a few of us. I came in an engineering role, but within, I think a year, had taken over the CTO role and have been doing that since.Corey: For those of us who've been living under a rock and recording podcasts, CI/CD or Continuous Integration/Continuous Delivery has gone through a bit of, shall we say, evolution since the term first showed up. My first exposure to it many moons ago was back when Jenkins was still called Hudson, and it was the box that you ran that it would wait for some event to happen, whether it was the passing of time, a commit to a particular branch, someone clicked a button, and then it would run a series of scripts, which sort of lent itself to the idea of the hacker news anthem, "That doesn't look hard. I can build that in a weekend." Now, we've seen a bit of growth in that space of not just, I guess the systems you can run yourselves, but also a lot of the SaaS offerings around this. That's the, I guess, the morons journey from my perspective to path through CI/CD. That's almost certainly lacking nuance. What is it, I guess in the real world with adults talking about it?Rob: Yeah, so I think it's a good perspective, or it's a good description of the perspective that many people have. Many people enter into this feeling that way. I think, specifically when you talk about cloud providers in CircleCI, we do have an on-prem offering behind the firewall. No one really runs anything on-prem anymore. But we have an offering for that market, but the real leverage is for folks that can use our stuff, multi-tenant SaaS cloud offering. Because, ultimately it's true. Many people have start with something simple from a code based perspective, right? I'm starting out, I've got a small team. We have a pretty simple project, maybe a little monolith Ruby on rails, something like that. Actually, I think in the time of the start of CircleCI. Probably not too many people kick off the rails monolith these days because if you're not using Kubernetes and Docker, then you're probably not doing it right.Corey: So, the Kubernetes and Docker people tell us?Rob: Yeah, exactly. They will proudly tell you that. We'll come back around to that point if we want to, but so you have simple project and you have simple CI, right? You may just have a simple script that you're putting in a Jenkins box or something like that, but what ultimately ends up happening is it gets complicated, and as it gets complicated, it becomes a bigger and bigger distraction from the thing that you're really trying to do, right? You're trying to build a business to ... I don't know, to do ride hailing, to do scooter sharing, what's big these days. You might be trying to do any of the ...Corey: Oh, my project is Twitter for pets. We're revolutionizing the world of pet communication.Rob: Right. And do you want to spend your time working on pet communication or on CI/CD, right? CI/CD is a thing that we understand very well, we spend our time on it every day, we think about some of the depths of it, which we can go into in a second. One of the things that gets complicated, amongst others, is just scale. So you build a big team, you have multiple projects and you have that one box under your desk where you said, "Oh, it's not that hard to build CI/CD. Now, everybody's waiting for their stuff to run because someone else got in there before them and you're thinking, okay, well how do I buy ... maybe you're not buying more boxes, you're building out something in a cloud provider and then you're worrying about auto scaling because it starts to cost you too much to run those boxes, and how do you respond to the amount of load that you have on any given day?Because you're crunching for a deadline versus everybody's taken a week off. Then, you want to get your build done as quickly as possible. So you start figuring out how to paralyze the work and spread it across those machines. The list goes on and on. This is the reality that everyone runs into as they scale their work. We do that for you. While it seems simple and ... I said I came in through an acquisition, we were building CI/CD for iOS, and I was that person. I said, "This seems really simple. We should build it and put it in the market." It didn't take us very long to get that first version to build, and it had to be generic to support many different types of customers and their particular builds.It was a small start but we started to run into the same problems, and then of course as a business, we ran into the problem of getting access to customers and all those things and that's why we joined CircleCI and that became what is now our iOS offering. But there is a lot of value that you can get quickly, to your point, but then you start focusing time and energy on that. I often refer to it, others in the industry refer to these sorts of things as undifferentiated heavy lifting. Something that becomes big and complex over time and is not the core of your business. Then as you start to invest in it, as we invest in it, then we build capabilities that most people wouldn't bother to build when they write that first bash script off a trigger or whenever, around helping you get your project set up, handling the connection into hooks, handling authentication so that different users only have access to the code they should have access to, maybe isolating access to production secrets, for example, if you're doing deploy.The kinds of things that keep coming up over and over in CI/CD that people don't think about on that first pass but ended up hunting them down the road.Corey: What do you think that people tend to misunderstand the most about CI/CD as you take a look at that throughout the ecosystem? From my perspective, when it was a box that you ran, behind the firewall as you say, the problem was is that everyone talked about, "Oh yes, we use cattle, not pets, except the box that does the builds. Of course, that box has a bunch of hand-built stuff on it that's impossible to replicate. It has extraordinary permissions into production environments and can do horrifying things, and it was always the star of various security finding reports. There are a number of us who came up from an operation side viewing CI/CD as, in some ways, a liability, which I understand is a very biased and one sided perspective. But going beyond that, what are people missing? What are they not seeing about the CI/CD landscape?Rob: One thing that I think is really interesting there, well, one thing you call that was just resiliency, right? We think about that in the way that we operate that system. We have a world of cattle because we've managed to think about that as a true offering. So, as you scale and you start to think, "Oh, how do I make this resilient inside my operation?" That's going to become a challenge that you face. The other thing that I think about that I've noticed over the years is, I want to call it division of labor or division of responsibilities. Many of those single instance or even multi-instance self-managed CI/CD tools end up in a place where, past any size of team, honestly somebody needs to own it and manage it to make sure it's stable.The changes that you want to make as a developer are often tied to basically being managed by that administrator. To be a little clear, if I have a group responsible for running CI/CD and I want to start building a different type of code or a different project, and it requires a plugin or an extension to the CI/CD platform or CI/CD tool, then I need to probably file a ticket and wait for another department who is generally not super motivated to get my code out into production, to go make a change that they are going to evaluate and review and decide ... or maybe creates conflict with something somebody else is doing on that system. And then you say, "Oh well actually we can't have these co-installed so now we need two systems." It's that division of responsibilities. Whereas, having built a multi-tenant cloud offering, we could never have that. There is no world in which our customers say to us, "Hey, we want this plugin installed. Can you go do that for us?"Everything that is about how the development team thinks about their software and how they want their build to run, how they want their deploys to run, etc, needs to be in the hands of the developers, and everything that is about maintenance and operation and scale needs to be in our hands. It has created a very clear separation out of necessity, but one that even ... I mentioned that you can deploy CircleCI yourself and run it within a team, and in large organizations, that separation really helps them get leverage. Does that make sense?Corey: It really does. I think we're also seeing a change in perspective around resiliency and how this works. I once worked at a company I will not name where they were. It was either CircleCI or TeamCity. This was years and years ago where I don't recall exactly what they were using, but it doesn't matter because at one point the service took an outage, and in typical knee jerk reaction, well, that can never happen again. So they wound up doing all of the CI/CD work for some godforsaken reason on a Raspberry PI that some developer brought in and left in the corner of the office. Surprise, it took an awfully long time for tests to run on basically an underpowered toy project. The answer there was to just use less tests because you generally don't need to run nearly as many.I just stared at people for the longest time when it came to that. I think that one of the problems that we still see, I know when I write code myself, I'm as guilty of this as anyone, I am a terrible developer and don't believe in tests. So, the CI/CD pipeline that I tend to look at is more or less a glorified script runner. Whenever I make a commit to this branch, go ahead and run the following three lines script that does a serverless deployment and puts it where it needs to go, and then I'll test it manually, or it's a pre-production environment so it's not that big of a deal. That can work for some use cases, but it's also a great thing that no one actually depends on the stuff that I write for day-to-day business operations or anything critical. At what point does it stop being a script runner?Rob: Well, to the point of the scale, I think there's a couple of things that you brought up in there that are interesting to me. One is the culture of testing. It feels like one of these areas of software development, because I was around in a time when no one really understood what it was to do automated testing. I won't even go into TDD, but just, in general, why would I do that? We have this QA team, it's cost effective to give it to a bunch of people. I'm thinking backwards or thinking back on that, it all seems a little bit well, wrong. But getting to the point where you've worked effectively with tests takes a little bit of effort. But once you have that, once you've sat and worked on something and had the feedback loop of, oh, this thing's not working. Oh, I'll just change this, now it's working.Really having that locally, as a developer, is super rewarding, in my mind and enabling I guess I would say as well. Then you get to this place where you're excited about building tests, especially as you're working in a team, and then culturally you end up in a place where, I put up a PR and someone else looks at it and says, "I see you're making an assumption or I believe you're making an assumption here, but I don't see any way that that's being validated. So please add testing to ensure that is actually true." Both because I want to make sure it's true now, but when we both forget that you ever wrote this and someone else makes a change, your assumptions hold or someone can understand that you were making those assumptions and they can make appropriate changes to deal with it.I think as you work in a team that's growing and scaling and beyond your pet project, once you've witnessed the value of that, you don't want to go back. So, people do end up writing more and more tests and that's what drives the scale at least on the testing and CI side in a way that you need to then manage that. Going the opposite direction of what you're describing, which is, hey, let's just write fewer tests and use cheaper machines, people are recognizing the value and saying, "Okay, we want that value, but we don't want to bottleneck everyone with an hour long build to run all these. So how do we get a system that's going to scale and support that?"Corey: That's what's fascinating, is watching that start to percolate beyond the traditional web applications with particular blessed languages and into other things. For example, in my copious spare time, I'm the community lead for the open guide to AWS, which is a GitHub project that has 25,000 stars or so, so you know it's good, where it's just a giant markdown document that lists the 10,000 tips and tricks that we all wish we'd known when we'd gotten started with AWS, and in a format that's easily consumable. The CI/CD approach we have right now, which I believe is done through Travis, is it just winds up running a giant link checker in parallel across the thousands of links that are ... sorry, I wanted to say 1,200 links, that are included within that document.There's really not a lot else we can do in that type of environment. I mean, a spellchecker with all of the terms of art involved would more or less a seg fault itself to death as soon as it took a look, but other than making sure we don't have dead links, and it feels like there's not a lot of automation or testing opportunity in something like that. Is that accurate? Am I completely wrong and missing something?Rob: I've never built that particular site so it ... I mean, it sounds reasonable. I think that going the other way, we often think about, before we kick off a large complex set of testing for a more complex application, maybe then a markdown document, a lot of people now will use things similar to what you're using, like maybe part of my application is a bunch of links to outside docs or outside sites that I'm referencing or if I run into a problem, I link you to our help site or something and making sure all that stuff is validated. Doing linting on the structure and format of code itself. One of the things that comes up as you scale out of the individual script runner is doing that work in parallel. I can say, you know what? Do the linting over here, do the link checking over here. Only use very small boxes for those.We don't happen to have Raspberry Pi's in our infrastructure, but we can give you a much smaller resource, which costs you less if you're not going to be pushing the limits of that. But then, if you have big integration tests or something which need more space than we can provide that as well, both in a single channel or pathway to give you the room to move faster and then to break that out and break up your work. At an extreme example, and of course, anyone who's done parallelization knows there's costs to splitting up work in like the management overhead. But if you have 1200 links, like you could check them all at the same time. I doubt that would be a good use of our platform, but you could check 600 in one and 600 in another, or 300s at a time or whatever, in find the optimal path if you really cared about getting that done more quickly.Corey: Right. Usually, it's not that big of a concern and usually it winds up throwing errors on existing bad links, not something that has been included in the pull request in question. Again, there's nothing that is so awesome that I can't horribly misuse it for something ridiculous. It's my entire stock and trade. It's why I believe route 53 remains the best database option for everyone, but it's fun going through this space and just seeing how things have evolved. One question I do have since you come from a background, by way of acquisition, that was aimed squarely at this, historically, it seems that running a lot of testing on mobile devices, specifically iOS devices, was the stuff of nightmares because you couldn't really run that in any meaningful way in a virtualized environment. So, it generally required an awful lot of devices. Is that still the case? Has that environment changed radically since I last worked at a mobile shop?Rob: I don't think so, but I think we've all started to think a little bit differently. We got started in that business because we were building iOS apps and thought, wow, the tooling here, it's really frustrating. To be clear, at CircleCI and at that business, we were solving the problem of managing the machines themselves, so the portion of the testing that you would run effectively in a simulator, not the problem of the device farm, if you will. But one of the things that I remember, and so this is late 2013, early 2014 as I was working on mobile apps was people shifting the MVC layers a little bit such that the thing that you needed to test on a device was getting smaller and smaller, meaning putting more logic in, I forget what the name was specifically, but it was like the ... I don't want to try to even guess.But basically pulling logic out of the actual rendering and down into what we'll call state transitions I guess. If you think about that in modern day and look at maybe web frameworks like React, you're trying to just respond with rendering on top of a lot of state change that happens underneath that. In that model, if you thin out the user interface portion, you make a lot more of your code testable, if that makes sense. The reason we're all trying to test on all these different devices is often that we've baked a lot of business logic into the view layer. Does that make sense?Corey: Yeah, it absolutely does. Please continue.Rob: Instead of saying, well, all our logic's in the view layer, so let's get really good at testing the view layer, which means massive device farms and a bunch of people testing all these things, let's make that layer as thin as possible, and there's analogies for this in even how we do service design these days and structure the architecture of systems, basically make the boundaries as thin as possible and the interaction with the outside world as thin as possible. That gives you much more capability to effectively test the majority or much larger portions of your business logic. The device farm problem is still a problem. People still want to see how something specifically renders on a particular screen or whatever. But by minimizing that, the amount that you have to invest in that gets smaller.Corey: This episode is sponsored in part by our friends at Uptycs, because they believe that many of you are looking to bolster your security posture with CNAPP and XDR solutions. They offer both cloud and endpoint security in a single UI and data model. Listeners can get Uptycs for up to 1,000 assets through the end of 2023 (that is next year) for $1. But this offer is only available for a limited time on UptycsSecretMenu.com. That's U-P-T-Y-C-S Secret Menu dot com.Corey: You mentioned device farm, which is an app choice, given that that is the name of an AWS service that has a crap ton of mobile devices that you can log into and it's one of my top candidates for the, did I make this service up to mess with you competitions? It does lead us to an interesting question. CI/CD has gotten an increased amount of attention lately from pretty much everyone. AWS, as is typical for Amazon, tends to lie awake at night worrying that someone somehow is making money that isn't them. So their product strategy distills down to, yes. So, they wound up releasing a whole bunch of CI/CD oriented products that at launch were, to be polite, terrible. Over time, they've gotten slightly better, but it's still a very confusing ecosystem there.Then we see things like Azure dev ops who it seems is aimed at a very similar type of problem and they're also trying to challenge Amazon on the grounds of terrible names of services. But we're now seeing an increased focus from the first party providers themselves around the CI/CD space. What does that mean for existing entrenched players who have been making a specialty out of this for a lot longer than these folks have been playing with it?Rob: It's a great question. I think about the approaches very differently, which is probably unsurprising. Speaking of lying awake at night or spending all day thinking about these things, this is what we do. You've the term script runner a few times in the conversation, the thing that I see when I see someone like AWS looking at this problem is basically, people are using, the way that I think about it, is maybe less the money, although it translates pretty quickly. People are using compute to do something, can we get them to do that with us? Oddly enough, a massive chunk of CircleCI runs on AWS so it doesn't really matter to them one way or another, but they're effectively looking to drive compute hours and looking to drive a pathway onto their platform.One thing about that is it doesn't really matter to them in my perspective, whether people use that particular product or not. As a result, it gets the product investment that you put in when that's the case. So, it's a sort of a check the box approach like, hey we CI and we have CD like other people do. Whereas, when we look at CI and CD, we've been talking about some of the factors like scaling it effectively and making it really easy for you to understand what's going on. We think about very much the core use case, what is one of our customers or users doing when they show up? How do we do that in a way that maximizes their flow? Minimizes the overhead to them of using our system, whether it's getting set up and running really quickly, like talk about being in the center of how much of the world is developing software.So we see patterns, we see mistakes that people are making and can use that to inform both how our product works and inform you directly as a user. "Hey, I see that you're trying to do this. It would go better if you did this." I think both from the, honestly, the years that we've been doing this and the amount that we've witnessed in terms of what works well for customers, what doesn't, what we see going through just from a data perspective, as we see hundreds of thousands of builds running, that rich perspective is unique to us. Because as you said, we're a player that's been doing this for a really long time and very focused on it. We treat the experience with, I guess I'm trying to figure out a way to say this that doesn't sound as bad as it might, but a lot of people have suffered a lot with CI/CD.There's a lot that goes into getting CI/CD to work effectively and getting it to work reliably over time as your system is constantly changing. Honestly, there's a lot of frustration, and we come in to work every day thinking about minimizing that frustration so that our customers can go spend their time doing what matters to them. Again, when I think you sort of ... a lot of these big players present you with a runtime in which you can execute a script of your choosing. It's not thinking about the problem in that way and I don't see them changing their perspective. Honestly, I just don't worry about them.Corey: Which is a very fair tack to take. It's interesting watching companies and as far as how much time and energy they spend worrying about competition versus how much they focus instead on customers. To turn it around slightly, what makes what you do challenging in some respects, I would imagine is that a lot of your target market is themselves, developers. Developers, in my experience, are challenging customers in that, first, they tend to devalue their own time to the point where, oh, that doesn't sound hard. I'll build that overnight. Secondly, once you finally win them over to the idea of paying for something, it's challenging to get them to have the necessary signing authority. At best, they become champions. But what you do has to start with developers in order to win widespread adoption and technical buy-in. How does that wind up manifesting as approach to, well, some people call it developer relations, developer advocacy. I refer to those folks as developers because I have problems, but how do you folks view that?Rob: Yeah, it's a really insightful view actually because we do end up in most of our customers, or in the environments of our customers, however you want to describe it, as a result of the enthusiasm of individual developers, development teams, much more so than ... there are many products certainly in enterprise software and I don't really think purely in enterprise, but there are many products that can only be purchased by the CIO or the CTO or whatever. Right? To your question of developer relations, we spend a lot of time out in the market talking to individuals, talking at conferences, writing content about how we think about this space and things that people can do. But we're a very product driven company, meaning both, that's what we think about first, and then support it with these other things.But second, we win on product, right? We don't win in the market because you thought the blog posts that we wrote was really cool. That might make you aware of us, but if you don't love the product, I mean, developers, to your point, they want to use things that they really enjoy using. When developers use the product and love the product and they champion it and they get access because they might work on a side project or an open source project or maybe they worked in another company that used CircleCI and then they go somewhere else and they say, "What are we doing? Life is so much better for you Circle CI, those sorts of things. But it very much comes from the bottom up. It's pretty difficult to go into an organization and say, "Hey, you should push this down to all of your developers."There's a lot of rejection that comes from developers on mandated tooling. We have to provide knowledge, we have to provide capabilities in our product that appealed to those other folks. For example, administrators of our tooling, or when it gets to the point where someone owns how you use CircleCI versus just being a regular user of the product. We have capabilities to support them around understanding what's happening, around creating shared capabilities that multiple teams can use, those sorts of things. But ultimately, we have to lead with product, we have to get in into the sort of hearts and minds of the developers themselves and then grow from there and everything we do from a marketing, developer relations myself, I spend a lot of time talking to customers who are out in the market, is all about propping up or helping raise awareness effectively. But there's nothing that we can do if the product doesn't meet the needs of our customers.Corey: That's what it seems like it comes down to a fair bit. It's always weird to consider that, at its heart, developer relations is marketing. The folks I talk to who argue against that, it seems that it comes from a misunderstanding of what marketing actually is. It's not buying ads in airports, it's not doing podcast advertisements. That's a subject near and dear to my heart. It's not about annoying people by showing up at their office with the sales team. It's about understanding what their challenges and problems are and then positioning a solution that ideally solves them in a place that and in a way that they can be receptive to. Instead, people tend to equate marketing to this whole ridiculous statistics driven nonsense that doesn't really resonate with anyone and I think that that's unfair to everyone involved.That said, I will say that having spent a fair bit of time in this space, I've yet to see anything from CircleCI that has annoyed me to the point where I would have remembered it, which is awesome. I don't see it in flight magazines, generally. I don't see it on obnoxious people try to tackle me as I walk through an expo hall and want to scan my badge. It just seems very well executed and you have some very talented people working for you. To that end, you are largely a distributed company, which is fascinating. Did it start that way? Did it happen that way by a quirk of fate?Rob: Yeah, I those two things probably come together. The company, from very early days, now I wasn't there but I think some of our earliest engineers were distributed and the company started out basically entirely as engineers. It's a team solving problems of other engineers, which is ... it's a fun challenge. There were early participants who were distributed. Mostly, when you start a company and no one has ever heard of you and no one knows if you're going to be successful, going and recruiting is generally a different game than when you're, certainly, when you're where we are now. There were some personal relations that just happened to connect with people around the globe who wanted to participate.We started out pretty early with some distribution, and that led to structuring the org in a way, both from a tooling and process perspective. A lot of that sort of happens organically, but building a culture that really supported that. I personally am based in the Bay Area, so we have headquarters in San Francisco, but it doesn't really make a difference if I go in versus just stay and work from home on any given day because the company operates in such a way that that distribution is completely normal.Corey: We accidentally did the same thing. My business partner and I used to live across the street from each other and we decided to merge a week before he moved out of state to Portland. So awesome. Great. We have wonderful timing on all of these things. It's fun to build it from that way, build that way from the ground up. The challenge I've always seen is when you start off with having a centralized office and everyone's there, except this one person who, no matter how you try to work around it, is never as involved. So it feels like the sort of thing you've absolutely got to be building from day one, or otherwise, you're going to have a massive cultural growing pain as you try to get there.Rob: Yeah, I think that's true. So I've actually been that one person. I, at some point in my career prior to CircleCI, was helping out a company founded by some friends of mine based in Toronto. I grew up in Toronto. I kicked off a project and then the project grew and grew until I was the one person out of maybe 50 or 60 who wasn't in an office in Toronto. It got to the point where no one remembered who I was and I was like, "Cool, I think I'm done. I'm out." I was fine with that. It was always meant to be a temporary thing, but I really felt that transition for the organization. I would say in terms of growing, I mean, yes, if you start out, it goes both ways, if you start out distributed, you're going to remain distributed.There are certain things that get more challenging at scale, right? If everybody is sort of just in their home all over the globe, then the communication overhead continues to increase and increase in just understanding who people are, who you should be talking to. You need to focus-Corey: There's always the time zone hierarchy.Rob: Ooh, the time zones are a delight, yes. I would say like we talk a lot about, in this industry, Dunbar's number and sizes of teams and the points at which things get more complex. I think there's probably a different scale for distributed teams. It takes fewer people to reach a point where communication gets challenging, and trust and all the other things that go with Dunbar's views. You kind of have that challenge and then you start to think, oh well, then you have some offices, because we actually have maybe six physical offices, partly because in our go to market org, we've started to expand globally and put people in regional offices.There's this interesting disconnect. I don't know about disconnect, but there's a split in how we operate in different parts of the org. I think what I've seen people ... well, I don't know about succeed, but I've seen people try when you start out with one org, or sorry, one location is, let's not jump to that one person somewhere else and then one person somewhere else kind of thing, but build out a second office, build out another office, like pick another location where you think you ... it's often, certainly where we are, in the Bay Area, it's often driven by just this market. Finding talent, finding people who want to join you, hanging onto those people when there are so many other opportunities around tends to be much more challenging. When you offer people alternatives, like you can stay where you are but have access to a cool and interesting company or you can work from home, which a lot of people value, then there's different things that you bring to the table.I see a lot of people trying to expand in that way, but when you are so office-centric, a second office I think is a smoother transition point than just suddenly distributing people because, especially the first and second one, unless you're hiring in a massive wave, are really going to struggle in that environment.Corey: I think that's probably one of the more astute things that's been noticed on this show in the last couple of years. If people want to hear more about what you have to say and how you think about the world, where can they find you?Rob: I would say, on our blog, I tend to write stuff there as do other people. You talked about having great people in the organization. We have a lot of great people talking about how we think about engineering, how we think about both engineering teams and culture and then some of the problems we're trying to solve. So, off our site, circleci.com, and go to our blog. Then, I attend to is to speak and hangout on podcasts and do guest writing. I think I'm pretty easy to find. You can find me on Twitter. My handle is z00b, Z-0-0-B. I know I'm not super prolific, but if someone wants to track me down and ask me something, I'd probably be more than happy to answer.Corey: You can expect some engagement as soon as this goes out. Thank you so much for taking the time to speak with me today. I appreciate it.Rob: Yeah, thanks for having me. This was a ton of fun.Corey: Rob Zuber, CTO at CircleCI. I'm Corey Quinn, and this is Screaming in the Cloud. If you've enjoyed this podcast, please leave a five-star review on Apple podcasts. If you've hated this podcast, please leave a five-star review on Apple podcasts along with something amusing for me to read later while I'm crying.Announcer: This has been this week's episode of Screaming in the Cloud. You can also find more corey@screaminginthecloud.com or wherever fine snark is sold.Announcer: This has been a HumblePod production. Stay humble.
Zbudowanie strony z dokumentacją od zera może się wydawać nie lada wyzwaniem. Istnieje mnóstwo sposobów na podejście do tematu. Kiedy myślimy nad potencjalnym rozwiązaniem, do głowy przychodzą nam następujące pytania: Czy można do tego celu użyć darmowych narzędzi? Czy istnieje coś takiego jak bezpłatny hosting? Jak pisać dokumentację bez CCMSa? Jak wygenerować PDFy bez użycia standardu DITA? W tym odcinku staramy się stworzyć prosty (i bardzo subiektywny) przepis, który pomoże Wam zbudować nowoczesną stronę z dokumentacją w relatywnie krótkim czasie. Dźwięki wykorzystane w audycji pochodzą z kolekcji "107 Free Retro Game Sounds" dostępnej na stronie https://dominik-braun.net, udostępnianej na podstawie licencji Creative Commons license CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/). Informacje dodatkowe: "#38 Tech Writer walczy z hakerami, czyli jak zadbać o bezpieczeństwo dokumentacji", Tech Writer koduje: https://techwriterkoduje.pl/blog/2022/01/10/tech-writer-walczy-z-hakerami Static Site Generator: https://www.gatsbyjs.com/docs/glossary/static-site-generator/ Docusaurus: https://docusaurus.io/ Algolia: https://www.algolia.com/ Markdown: https://daringfireball.net/projects/markdown/syntax Visual Studio (VS) Code: https://code.visualstudio.com/ VSCodium: https://vscodium.com/ Rozszerzenie Vale dla VS Code: https://github.com/errata-ai/vale-vscode Git: https://git-scm.com/ GitHub: https://github.com/ GitHub Pages: https://pages.github.com/ GitHub Actions: https://github.com/features/actions Repozytorium dla strony Tech Writer koduje: https://github.com/techwriterkoduje/site-source TeamCity: https://www.jetbrains.com/teamcity/ Jenkins: https://www.jenkins.io/ Kubernetes: https://kubernetes.io/ Docker: https://www.docker.com/ DITA Open Toolkit (OT): https://www.dita-ot.org/ Oxygen XML: https://www.oxygenxml.com/ mr-pdf: https://www.npmjs.com/package/mr-pdf
Chris is back from vacation and gives hiring and onboarding updates. Steph has an update about the CI slowdown and scaling CI. They tackle a listener question regarding having some fear around potential merge conflicts. This episode is brought to you by ScoutAPM (https://scoutapm.com/bikeshed). Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Deckset (https://www.deckset.com/) parallel_tests (https://github.com/grosser/parallel_tests) paralleltests - important line that may alter the `groupby` strategy (https://github.com/grosser/parallel_tests/blob/9bc92338e2668ca4c2df81ba79a38759fcee2300/lib/parallel_tests/cli.rb#L305) KnapsackPro (https://knapsackpro.com/) rspec-queue (https://github.com/conversation/rspec-queue) Vim Conflicted Overview (https://github.com/christoomey/vim-conflicted#overview) Mastering Git Course on Upcase (https://thoughtbot.com/upcase/mastering-git) Git Object Model (https://thoughtbot.com/upcase/videos/git-object-model) Git Object Model Operations (https://thoughtbot.com/upcase/videos/git-object-model-operations) The Opportunity Will Find You (https://thoughtbot.com/blog/the-opportunity-will-find-you) This episode is brought to you by Studio 3T (https://studio3t.com/free). Try Studio 3T's full suite of features for 30 days, no payment details needed. Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: CHRIS: Golden roads are golden. STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. Oh, I also have a new intro that I want to try out. This is thanks to Irmela from Twitter, where it's good morning and hooray; today is Bike Shed day. They technically said Tuesday, but we don't record on Tuesdays. So today is Bike Shed day, so happy Bike Shed day. And hey, Chris, what's new in your world? CHRIS: What is new in my world? Yeah, I loved when I saw that tweet come out. It really warmed my heart. So Tuesday, in theory, is Bike Shed day, but for you and I, Friday is Bike Shed day. It's confusing breaking the fourth wall, as I so often do. But yeah, what's new in my world? I'm back from vacation, which is the thing that I did. For listeners, well, I have been absent the previous week related to vacation and all those sorts of things. But I did what we're going to describe as a not smart thing. It wasn't intentional. The world just kind of conspired in this way. But I had two separate vacation islands that existed in my mind, and then they both kind of congealed, but as they did that, they moved towards each other, but they didn't connect. And so what I ended up with was two weeks back to back where I was out on Thursday and Friday of one week, and then I was back for Monday and Tuesday. And then I was out for Wednesday, Thursday, Friday of the following week. Protip: that's a terrible idea. It's just not enough time to sort of catch up. The whole of it was like the ramp-up to vacation and then the noise of vacation, then getting back and being like, oh, there are so many emails. Let me try and catch up on them. But also, on the very positive side, we had a new hire join the team, and so most of my focus on the days that I was in the office was around getting that new person comfortable on the team, onboarding, spending as much time as possible with them. And so, all total, it was an adventure. And again, I would strongly recommend against this. The world just kind of conspired, and suddenly these three different forces in my life came together. And this was just the shape of things. But yeah, I went on vacation, and it was great. The vacation part was great. STEPH: I will take your advice. So next time I have like two segments of PTO, I'm just going to stitch them together and just go ahead and take that whole intermittent time off. CHRIS: That probably would have been better. Again, someone new joining the team, it was very important to me to get some time with them early on, and so I opted not to do that. But yeah, the attempt to catch up in between was a completely lost effort, I would say. But I think I'm mostly caught up now, having been back in the office for about a week, so yeah. But let's see, what else has been up in my world? It's actually been a while since you and I have chatted based on the various timing and schedules and the nonsense vacation schedule that I had that you so kindly accommodated across a couple of weeks. Let's see, hiring and onboarding; the hiring went really well. We talked about that a bunch of weeks back. But now we're in the onboarding phase. And so next week will be the first week that all four of us on the engineering team are in the office together for the full week. I'm super excited to experience that. We've had different portions of it, with me being on vacation and other folks being on vacation. But now, for the first time, we're really going to feel what it's like as this team. And we're going to have our first retro as a group and all those sorts of things, so I'm very excited to do that. And thus far, all of the interactions that we've had have been really wonderful as a team. And so now it'll be the first time we're just bringing all of those various pieces together. STEPH: I just have to clarify; you said all of y'all in the office together. Do you still mean remotely? CHRIS: Oh, yes, yes, I just mean not on vacation, all present and accounted for on the internet. Remote is another interesting facet of what we're doing here and trying to figure out how to navigate that, particularly where there are some folks that are closer and can potentially get together in the city, that sort of thing, and then folks that are truly remote and making sure that we're...I'm very much of the opinion if we have anyone that's remote, we are remote team, and we must embrace async communication and really lean into that. And I think the benefits of async communication as its own consideration are so worth it. And it's one of those things that's hard to do. It requires careful, intentional thought. It requires more purposeful communication. But I think there are a lot of good things that fall out of that. It's similar to TDD in that way in my mind, like, it's not easy. It's actually quite difficult. But all the effort that I put into trying to learn how to do that has made me a better developer, I think, on all the various fronts. And I think similarly, async communication I believe in as a tool to force just better communication. And so I'm a big believer in it, and I've found a ton of benefit in remote that I'm also a big believer in that now. I, like everyone else, was forced into it as the world was, but I've really come to enjoy it a lot. And so yeah, so, no, not physically in the office, to answer your very short question with a long rambling aside. STEPH: [laughs] I like that comparison. I hadn't thought about it in that way but comparing that thoughtfulness and helpfulness of async communication and then also to TDD, where it's not easy, but the payoff is so worth it, the upfront cost of it. That is something that at thoughtbot, we've had conversations around where there are folks that really value...they want to be around people. They get energy from people, and so they want that option to be able to rent a WeWork space and maybe get together with a colleague once or twice a week, and that was supported by thoughtbot. But we also wanted to express well, if you are together, do treat everything still as a remote work environment. So let's say if you and your colleagues are on a project, but then there's a third person on that project that's remote, you still need to act like everything's remote to make sure that everyone else is still getting to participate and hear everything and be part of the conversation. So just keeping that in mind that yes, we want to support you doing your best work, and if that's around people, that's wonderful. But we are still remote-first, and communication needs to be in that fashion. Well, that's super exciting that you'll have all of the team together. That sounds like it will be wonderful to hear about and then also retros and meetings, and yeah, it sounds like you've got a fun week ahead. CHRIS: Indeed. I'm super excited to see what sort of new things come out of the new voices on the team and practices that each of the individuals have experienced at other companies that we can now fold together. The work that we've done so far has been very much inspired by thoughtbot ideas, and approaches, and workflows, and processes because that's what I brought to the table. But I'm super excited to bring in more voices and see what of that 100% stays on versus does anything change? Do we get entirely new things? So yeah, very excited about all of that. But to revisit a topic that we've talked about in the past, this week is catching up from vacation, so there's a certain amount that will constrain my work. But this was definitely another week of I did not do much coding. I'm trying to think if I did any coding this week. It's possible that the answer is no. The fact that I don't even know the answer to that is an interesting one. I still have in my mind the desire to get back to it, and I think I will. But there's so much other stuff to do. Recently, this week, there's been a lot of vendor selection and contract negotiation, which is an interesting facet of the work, but just trying to figure out, oh, we need platforms to do X, Y, and Z. And it turns out they're wildly costly and have long sales cycles. And how do you go through that, and how do you make sure that we're getting the right thing? And so that's been a big part of my work. Hiring and onboarding, again, has been a big part of it. There's also some amount of communicating back to the broader team - what are we doing? What is the product organization or the engineering team delivering? And so I'm okay at presentations, I think. I'm comfortable with giving presentations. The thing that I struggle with is finding the optimization point in preparation. I will, of my own accord, over-prepare. And that may sound a little bit like, oh, what's my greatest weakness? That I care too much. But I mean it sincerely as like, I would love to find that right amount of like, it's like an hour of preparation for a 15-minute presentation to the team. That's the right ratio. And I just hit that on the head, and it's great. But whenever I know that I need to give a larger presentation, it will distract me. And it's work that can expand to fill whatever time you give it, and so trying to thread that needle is a tricky one for me. STEPH: Yeah, I'm with you. Presentations, for me, they're one of those things that it's very stressful, anxiety-inducing; all the prep feels distracting from some of the other work that I want to do. Or maybe I'm excited about the presentation, and that is the work that I want to do. But it's not until it's done that then I'm like, oh, that was fun. That went well. This was great. It's not until after that then I feel good about it. So the lead-up to it is very stressful. And so if you can optimize that to say, well, I know exactly what this group needs, where I can cut corners, where I have to go into details, that sounds incredibly valuable. I'm curious, so this is probably a bad idea, but it's the only way I really know how to find those boundaries is you got to experiment and tweak a little bit and let yourself fail a little bit or just be very explicit with folks about this is what the presentation is, if you expected something else, let me know. Or here's what I've got, have someone to bounce ideas off of. But there's such a nicety if you can find that I'm going to try failing just a little bit and get some feedback. Or maybe it's not failing at all, but you are testing that boundary to find out did this work, or should I put more effort into this? I'm curious, do you have thoughts on that? How you're going to find that right optimization level? CHRIS: Not as specific to truly honing in on whatever the correct number is. The thing that I've been doing is I...this will sound complicated, but I wait until the last minute but a specific version of the last minute. So at most, I start working on it an hour and a half before the meeting. And these are, again, not particularly large presentations, and it's a recurring sort of thing. So it's sort of engineering talking about the work that we've done recently and trying to find the right level of detail and whatnot, so giving myself a smaller time window. I think that's enough time to tell the story and to find a meaningful way to tell the story and grab the screenshots and all of that, but it's constrained so that I don't over-optimize, over-edit, overthink. I'm using Deckset, which is a presentation tool that starts from a Markdown file. So it's just a Markdown file that I'm editing. That's great; that works really well. I do not twiddle with fonts. There's one theme that I use. It is white background with black text. That's it. And I think I've given myself deep permission to be the CTO that has a white background with black text and no transitions. I don't even go into presentation mode for it. I'm literally showing the UI of Deckset, and then just hitting the arrow to move between them. But the Chrome and the drop-down menu at the top is still visible because I want to see people's faces as I'm presenting. And I haven't figured out how to do that correctly on my computer. So I'm just presenting the window of Deckset. And I'm like, I have given myself permission to do all of those things, and that has been super helpful, actually. So that's a version of me negotiating what this means. Where I do invest the effort is trying to enumerate all of the things and then understand what is the story that I'm telling around the things and how do I get the message right for the collective audience? So, for a developer team, I would say much more nuanced technical things, for marketing folks, it would be at this end of the spectrum. I do lean on the old idea of, like, let us talk about it in the mindset of the user, so it's very much user-centric, but then some of the things that we're doing are important but invisible to the users. They're part of how we broadly build the platform that we need to, but they're completely invisible to users. And so, how do I then tell that story still with ideally a user-centric point of view? So that's where I do invest the time, and I give myself complete freedom to just grab screenshots, put black text on a white background, and then talk over it. STEPH: I love it. Because you made this comparison earlier, so now I'm thinking of a comparison of like TDD-driven presentations where it's like, what's the end goal? What's the assertion? What's the outcome that I want? And then backfilling from there. Or, in your case, you're talking about what's the story that I need to tell? What's the takeaway that I want people to have? So then you start there, and then you figure out what's the supplemental information that you need to provide to then get there. And the fact that you don't twiddle with fonts and all that stuff, I think you're already really on your way [chuckles] in terms of finding that right optimization of I need to present a clear and helpful message but not sink too much time into this CHRIS: Black text on a white background is very clear. So... STEPH: [laughs] If there are any designers listening to this, they might just be cringing to this conversation right now. [laughs] CHRIS: I actually wonder about what the...I know that dark mode is a thing that lots of folks care about. I'm thinking about the accessibility affordance of it now. I'm actually thinking through it now that I said it somewhat flippantly. I actually don't know what I'm talking about, but it was easy, and it wasn't a choice that I allowed myself to think about. So there we are. Mid-roll Ad Hi, friends, and now a quick break to hear from today's sponsor, Scout APM. Scout APM is an application performance monitoring tool that's designed to help developers find and fix performance issues quickly. With an intuitive user interface, Scout will tie bottlenecks to source code so you can quickly pinpoint and resolve performance abnormalities like N+1 queries, slow database queries, and memory bloat. Scout also recently implemented external service monitoring, adding even more granularity when it comes to HTTP requests and API calls. So give Scout a try today with a free 14-day trial and experience first-hand why developers worldwide call Scout their best friend. And as an added bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. To learn more, visit scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. STEPH: In my personal world, so Tim and I are moving. We're on the move. We are transitioning from South Carolina to North Carolina. So I think I may have shared a bit of this news, but Tim has acquired his first software developer job, which is just phenomenal. It is in North Carolina. He does need to be there in person for it. So we are currently selling our South Carolina house and then moving. It's not too far. It's like three and a half hours away to where we're moving in North Carolina because we're already pretty far in North and South Carolina. So yeah, there's always another box that needs to be packed. And there's always just something else that you forget, another thing that you want to take to Goodwill or try to give to a neighbor. It's a good way to purge. I will definitely say that every time you move, it's a good time to get rid of things. CHRIS: That is a very cup half-full point of view on it, but yeah, it feels true. STEPH: [laughs] It's true. I'm a very cup half-full person. For more technical news, for more client stuff that I've been working on, so I think the last time we chatted, I was sharing that we had this mysterious CI slowdown where we were going from CI builds taking around 25 minutes to spiking to 35, sometimes 45 minutes, and I have an update there. So we found out some really great things, and we have gotten it back down to probably more about 23 minutes is where the CI is running currently. As for the actual who done it, like what caused this specific slowdown, we got to a point where we were like, we're doing so much investigative work to understand exactly what caused this that it felt less helpful because at the end of the day, we really just wanted to address the issue. And so solving the mystery of exactly what caused this started to feel less and less meaningful because we're like, well, we want to improve this anyways. So even if we found that one line or something that happened that caused this, we want a bigger solution to this type of problem because then this could happen again like, someone else maybe adds one line or something happens, and things get thrown off balance, and then suddenly, we have a slowdown, and that just takes too long to investigate. So I don't have a concrete who done it answer for the slowdown. But we've learned a couple of things; one of the things that we learned is we're using parallel_tests to then split our tests across all of the CPUs that are then running the RSpec test. And we realized that we weren't actually splitting tests based on runtime data. So there are a couple of ways that paralleltests will let you divvy up your test, and two of those ways one is file size. So you can split the files based on the size of the file, or you can use info from the runtime log. So then paralleltests can be a little bit more intelligent about like, well, I know how long these files take, so I'm going to split it based on that versus just the size of the file. And we realized that we were defaulting and using the file size instead of the runtime even though we all thought we were using runtime. And the reason for this took a bit of source code diving because looking at the README for paralleltests; it looked like as long as we're passing in a file to the runtime log path, then paralleltests is going to use that runtime data. But then there's some sneaky-sneaky in there that I'll actually link to in the show notes in case anybody's interested. But if you are setting a particular flag and don't pass in another flag, then paralleltests is going to be like, cool, I'm going to portion out your test based on file size instead of the runtime. So we fixed that, or we updated that, and that has had a significant improvement for the test being split out more evenly. So we didn't have a CPU that was taking 25 minutes while the next CPU was only taking like 17 minutes. And paralleltests also provides some really helpful data that because we have that runtime log file, we could tell how long each CPU is running and how they're getting split. So the past couple of weeks, it's heavy measure, measure, measure, take all the data, create lots of graphs, understand what's happening, and then look for ways to then fix it. So figuring out how these files or how the tests were being distributed across, we had a number of graphs that were just showing us what's actually happening. So then we could track the improvement, so that was really nice. It was the measure twice and change something once [laughs], and then we got to see the benefit from it. For scaling the CI, so we are looking on adding more machines to then process tests. That has been really interesting because we're at the point where we are adding more machines, but if we add more machines, we're not going to speed up how quickly our CI processes everything. Because we are splitting tests based on file size and not by examples, we're always going to have this effect of a tentpole. So if we have a file that takes 10 minutes, that's the fastest we're ever going to get. So Joël and I are in discussions right now of where we still really want to understand what's the fastest we can achieve just by adding another machine or two versus are we at the point that, okay, scaling horizontally and adding more machines has been helpful, but we have reached the breaking point where we actually need to divvy out the tests at a smaller scale and have a queue approach? So then that way, we can really harness the power of then we don't have one file that takes 10 minutes, and we don't have to care either. So if somebody adds a test to a file and suddenly a file goes from 12 minutes to like...well, hopefully, they added more than one test. [laughs] But let's say it goes from 10 minutes to 15 minutes; we don't want to have to manage that and understand that there's a tentpole. We just want to be able to divvy out all the examples and then have a queue approach. That's probably going to be MVP two of this, but we're still waiting that out. But it's just been really interesting to realize that scaling horizontally really only takes you so far. Like, we've added one machine, maybe one more, so then we'll have three total. And then it's like, okay, that's great, but now we need to actually address this other bigger problem. CHRIS: I know we've talked about this in previous episodes, but I'm super interested to hear as you progress into the queue approach because that's something that's been top of mind for me for a while. I don't know if we've talked about it before specifically, but Knapsack Pro is the one thing that I'm available as a service that does this. Do you have other tools that you're looking at for that, or is this still in the exploratory phase? STEPH: Knapsack is still a top contender. There's also RSpec Queue; that's another one that we have in mind. Unfortunately, I really wish paralleltests let us do this, but paralleltests just doesn't quite offer that feature. And someone in the team, I think, even reached out to the maintainer of paralleltests, and they were like, "Yep, you're totally right. We're actually more focused in making sure that this works for everybody versus has specific features." And they gave a really nice thoughtful response, which we appreciated, so at least we could confirm that paralleltests won't do exactly the thing that we need. So yeah, RSpec Queue, Knapsack, I think those are the top two that I'm familiar with. CHRIS: Gotcha. I don't know if I've seen RSpec Queue before. I'm intrigued. So actually, an interesting thing happened. While I was away on vacation, one of the folks who just joined the team as one of their first steps joining the team, noticed that our CircleCI config wasn't actually taking advantage of the parallelism that we had configured; that's on me. I turned on parallelism and then never did anything with it, which is a complete waste. And so I was super happy to come back and saw that CI, which had been creeping up to six or seven minutes, had suddenly dropped back down to two to three minutes sort of thing. I was like, this is amazing. But now I'm at the point where our RSpec suite is spreading across the different, I think, it's like four different cores that we have available, but it's not doing it as efficiently as we would like. So I'm like, oh, okay, can we dial it up to 11? But I'm intrigued; I've only looked very much in passing at RSpec Queue literally now that you've mentioned it. But Knapsack Pro exists as a different service. And so, as far as I understand, the agent that's running is going to communicate and say, "Give me another test. Give me another test." But there needs to be some external process running and managing that queue. Does RSpec Queue do that? Somebody owns the queue, right? Who owns it? Do you understand how that works? STEPH: So I was definitely familiar with this. If you'd asked me a couple of weeks ago, when I was diving heavily into the queue work before then, we transitioned more into focusing on then adding new machines; I was very up to speed on this. So I may get a couple of things wrong, but my understanding is that RSpec Queue, you're going to manage your own queue. So you bring in the gem and then use something like Redis, so then you are in charge of that. And with Knapsack, then you are using their service to manage that queue. And then they have found ways to optimize around what if you can't reach their API or something; their service is down? And making sure that that doesn't impact your CI so then you can't still run your test just because you can't reach their queue somewhere. So that's my current understanding, RSpec Queue you own it, Knapsack they're going to own it. CHRIS: Gotcha. That makes sense. That about maps to what I was expecting, and so I wonder if I could use RSpec Queue. Now I'm going to have to go research that. But it's always nice to have new things to look at on this to go at ludicrous speed. That's what I'm going for. I want to get to ludicrous speed for our CI. STEPH: I like that name. I haven't heard of that speed. I feel like I have. I feel like you've dropped that before, [laughs] like you've used that. CHRIS: I don't know; quite possibly, I have. It's a Spaceball's reference. It's a throwback to days of old. STEPH: Well, then we may be investigating RSpec Queue together. Because yeah, Joël's and I goal for this week has been very much to figure out what's our boundaries with TeamCity? What are our boundaries with horizontal scaling? And I think we're both getting to that conclusion of like, okay, this has been good, it's helpful, but we really need to look into the queue stuff if we really want to see significant progress. Also, some of the stuff we're doing because we're pushing on it, we are manually splitting files. So if there's a file that has created this tentpole that's taking 10 minutes, but we know ideally most of the other files only take six minutes, then we are splitting that file, so then we have two spec files that are associated with the same class. And then using that as a way to say, okay, what would this look like? Let's say if this were better balanced. And that's also been pushing us in the direction of like, okay, this is fun, this is informative, but it's not sustainable. We don't want to have to keep worrying about splitting these files and doing this manually and pushing us towards that queue-based approach. MIDROLL AD: And now a quick break to hear from today's sponsor, Studio 3T. When you're developing applications, it can often be a chore to work with your underlying data. Studio 3T equips you with a complete set of tools to work with MongoDB data. From building queries with drag and drop, to creating complex aggregation pipelines; Studio 3T makes it easy. And now, there's Studio 3T Free, a free edition of Studio 3T which delivers an essential core of tools. This means you can get started, for free, with Studio 3T Free and when you're ready, you can upgrade and enjoy even more features through Studio 3T Pro and Studio 3T Ultimate. The different editions unlock more tools and additional integrations with Mongo DB, SQL, Oracle and Sybase. You can start today by downloading Studio 3T Free, which also includes a 30 day free trial of all the features of Studio 3T Ultimate, so you can try out some of the enterprise features as well. No credit card required. To start your trial head to studio3t dot com forward slash free. That's studio dot com forward slash free. But shifting gears just a bit, we have a listener question. So this person wrote in, "I have listened and loved your podcast for many years dreaming of getting a job with people half as thoughtful and intentional as you, and finally it happened. I have my first junior dev job, and my co-workers and bosses are all super awesome. Up until now, I've been flying solo. And in my new job, I've been finding it very unsettling to resolve merge conflicts. As careful as I am to comb through the conflict and contact the other developer if needed, I feel like I am covering my eyes and crossing my fingers whenever I select the resolve conflict button. Is there some type of process or checklist I could rely on? Is it normal to have such a high fear factor with a merge conflict? Any advice or maybe just a bit of been there felt that way...?" All right. So one, that's fabulous, congratulations on the new job. That's very exciting. I think I've voiced this many times, getting your first junior dev job is so hard, and so I'm so excited when it works out for people, and they get there. And then, for the merge conflict, I have thoughts. Chris, do you want to start? Shall I start? How are you feeling? CHRIS: Why don't you start? Well, actually, I'm going to add some pre-commentary, and then I think you should lead into our actual answer. But first, I just want to say a deep thank you to this listener for sending in the question. Again, we really love getting these questions. And also, thank you for the very kind words. To be clear, listener, if you're going to send in a question, you don't have to say very kind words, but they are really wonderful to hear and especially to hear if we had any part in helping this person feel more comfortable getting into that first dev role and having an idea of what maybe a good version of that could look like. Additionally, I really love the shape of this question because it gets into the people stuff and the tech stuff, so I'm super excited about this question. Actually, both Steph you and I responded very quickly to this one. And so it really did catch our attention because I think it crosses that boundary in an interesting way that I think is sort of The Bike Shed space in the world. But to that end, you did reply first in our email chain. So I think you should start, and then I'll follow on after that. STEPH: I should also check with you. Wait, so you don't have a filter on your email that's like kind words only to The Bike Shed, and then you filter out anything that's negative? CHRIS: I have a sentiment analysis, and if it's even neutral, it gets sent straight to the trash, only purely positive. No, constructive feedback is welcome too. We would love to hear that. Well, love is a strong word. We would accept it into our inboxes and then deal with it, but yeah. STEPH: [laughs] It will be tolerated. Must require at least three hearts in all emails; just kidding. [laughs] CHRIS: Are you kidding? I'm counting them now, and I see a lot of hearts in our emails. [laughter] STEPH: Merge conflicts. So is it normal to have such a high fear factor with a merge conflict? I'm going to say absolutely. Resolving a merge conflict can be really tricky and confusing. And I think; frankly, it's something that comes with just time and practice where then you start to feel more confident. As you're resolving these, you're going to feel more comfortable with understanding what's in the branch and the code changes that you're pulling in versus something that you need to keep on your side. So I think over time, that fear will subside. But I do think it's totally normal for that to be a very scary thing that then takes practice to become accustomed to it. As for if there is some type of process or checklist, I don't know of a particular checklist, but I do have a couple of ideas. So one of the things that I do is I will often push my code to whatever management system I'm using. So if I'm using GitHub, then I'm going to push up my branch because then, at least that way, someone has a copy of my work. So if I do something and I completely botch it locally, I know I can always reset to whatever it is that I pushed up to GitHub, so then that way, I have more freedom to make mistakes and then reset from there. So that is one idea is just put it somewhere that you know is safe, so that way you now have this comfortable sandbox to then make mistakes. The other one is run the test. So hopefully, the application that you're working with has tests that you can trust; if not, that could be another conversation. But if they do have tests, then you can run those, and then hopefully, that would let you know that if you have left something in, like maybe you left a syntax error, or maybe you removed some code that you shouldn't have because you weren't sure, then those tests are going to fail, and they'll let you know that something went wrong. And you can run those while you're still in the middle of that merge conflict as long as you've addressed like...well, no, if you haven't addressed syntax errors, that's still a time that you can run it, and it's going to let you know that you haven't caught all of the issues yet. So you don't have to wait till you're done to then go ahead and run that. A couple of other ideas, practice. So go ahead and create your own merge conflicts on purpose. So this is something that I think is really helpful because it will teach you, one, what causes a merge conflict? Because now you have to figure out how to create one, and then it will help you become comfortable because you're in a completely safe place where you have made up the issue, and now you're having to resolve that, so it'll help you become more confident in reading that merge conflict message. And then last but certainly not least, grab a buddy so if you are just feeling super nervous. Anytime I'm doing something that I just feel a little nervous about, then I just ask someone like, "Hey, would you look over my shoulder? Would you pair with me while I do this?" And I have found that's incredibly helpful because it eases some of my fear. I've got someone else that is also looking through this with me. But I also find it really helpful because then it encourages that person to be like, hey, if they're ever in a spot that they need to pair, I want them to know that they can also reach out to me and have that same buddy system. I guess that's my checklist. That's the one I would create. How about you, Chris? What do you think? CHRIS: Well, first, I just want to say that basically everything you said I 100% agree with, and purposely I think was great that you actually replied to the email first and that you're saying those things first because I think everything that you said is true and is foundational. And it's sort of the approach that I would definitely recommend taking as well. My answer, then adding on to that, has to do with how I've approached learning about this space in my own career. To name it, to answer the core question, is it reasonable to be scared of this? Yes, Git is confusing. Git is deeply confusing. I absolutely love Git. I have spent a lot of time trying to understand it, and in understanding it, I've come to love it. But it's only through deep effort that I've gotten to that place. And actually, the interface, the way that we work with Git on a day-to-day basis, particularly the command line is rough. I'm going to say, what does Git checkout do? Well, it does just about everything, it turns out. That command just does all of the stuff, and that's too much. It's, frankly, the UI for Git, specifically the command-line user interface; the commands that we run to manipulate the Git history are not super intuitive. But it turns out if you pop open the hood, the object model underneath the core way that Git stores your code is actually very simple. I find it's very easy to understand, but I, unfortunately, have found that I can't understand it without dropping down to that level. And so, in my own adventures, I kind of went deep on this topic a couple of years ago, and I created a Vim plugin because obviously, that's the best way to encapsulate your knowledge about Git, and so I created a plugin called Vim Conflicted. I don't necessarily recommend the plugin. It's fine if you want to use it. I don't do a great job of maintaining my plugins at this point, to be honest. But there was a weekend where I was trying to understand the world of Git and merge conflicts in particular, and it was really sort of fighting me. And as I started to understand it better, there's a little diagram that I drew on the README that I think is probably the most interesting artifact from it. But it's this idea that there are actually four files, four versions of a given file involved in any merge conflict. And that realization shifted my thinking a good amount. And then as I started to think about that, I was like, oh, okay, and then I want to see this version of it, and this version of it, and this combination, and the diff between these two, and that was super helpful for me. More generally, I also made a course on Upcase about Git as I tried to understand it better. And there are two particular videos from the middle of the course named the Git Object Model and Object Model Operations. And again, those two videos deal with popping the hood on Git, looking inside it, and what actually is happening to your code as you perform different Git operations. One of the wonderful things about Git is it is immutable. So you're never going to destroy your Git history if you've committed. So one of the rules that I have is just always be committing, never worry about committing. If you've committed, you can always get back to that version. You would have to try very hard to destroy committed code in Git. It's the things that you do when you haven't yet committed the code that are dangerous. So commit the code, like you said, Steph, push that up to GitHub, so you have a backup of it. You will have a backup locally as well, and that's a thing that you can come to be more comfortable with. But then, from there, there's actually a lot of room to experiment and play around because there's a ton of safety in the way that Git stores the code. You do have to know how to get at it, and that's the unfortunate and tricky part. But I think, again, to sort of summarize, yes, this is confusing. Your feelings are absolutely valid and totally grounded, but it is also knowable, is what I would say. And so, hopefully, there are a couple of breadcrumbs that we've laid there in how you might go about learning about it. But yeah, find a buddy, watch a video or two, and give it a try. This is definitely a thing that you can get there but totally reasonable that your first approximation is this is confusing because it sure is. STEPH: I often forget that Git has that local copy of my code, so I'm so glad you mentioned that. And then yeah, I saw when you linked to Vim Conflicted. The diagrams are great. I had not seen these before. So yeah, I highly recommend folks take a look at those because I found those very valuable. CHRIS: In that case, it's a white background, but I allowed myself to use some colors in the little images to help differentiate the different pieces. And it's an animated diagram, so it's really a high bar for me. [laughs] STEPH: So now the question is, did you go too far? Have you over-optimized? [laughs] CHRIS: I'm going to be honest; it was a weird weekend. STEPH: [laughs] Well, I don't think you've over-optimized. I do think it's wonderful. And I think this is definitely a reference that I'll keep in mind for folks whenever they're learning about merge conflicts or just want to get more knowledgeable about them. I think these diagrams are fabulous. CHRIS: Well, thanks. Yeah, I hope...they frankly were a labor of love, and the course is three and a half hours of me rambling about Git, so hopefully, it's useful to folks. If anything, it was super useful to me because my understanding of Git was deeply crystallized in making that course. But I do hope that it's useful to other folks. And particularly those two videos that I highlighted, I think are the ones that have been most impactful for me in terms of how I think about working with Git and getting comfortable with it. STEPH: Do you still receive emails every now and then from people, or maybe they are tweets from people that are like, "Hey, I watched one of your videos and found it really helpful." I feel like I still see that every now and then where people are just commenting on like, they watched some of the content that you created for Upcase a while back, and I think that's really cool. I'm curious if you still see that. CHRIS: I do, yeah, from time to time. It is absolutely wonderful whenever I hear that. Again, listener, do not feel the need to send me anything, but it is nice when I get them. STEPH: It does seem like I'm fishing for compliments now. [laughs] CHRIS: It does seem like that. So I want to be clear that's not what's going on here. But it is nice because I do actually forget that they're out there. But a lot of the stuff that I produced for Upcase, in particular, I tried to do more timeless stuff, so like the Vim content was really about how Vim works in a deep way. And the tmux course and the Upcase course...or the tmux course, the Git course. I look back at them, and a couple of little syntactic things have changed. But I'm still like, yeah, I agree with me from six years ago or whatever it was. Oh, that's a weird number to say, and I think is honest. It's fine. I'll just be over here. [laughs] STEPH: [laughs] That's helpful to hear, though, because that's always one of my fears in creating content. It's like, I don't know, it's okay if it's more opinionated and I change my mind and disagree with my past self. But it's more like, yeah, keeping up with is this still accurate? Is this still reflective of the times? And then having to keep that stuff updated. Anywho, that's a whole big thing, content creation. CHRIS: Content creation, but there's a parallel to it that many folks will not be creating content, and I think that's a very fine and good way to go about progressing on the internet. But there's a parallel to it in learning that I think is useful. I, at this point, will typically lean in if there is something in the SQL layer that is fighting me. I have never found effort spent trying to better understand the structured query language to be wasted time. Similarly, Git is one of those tools that is just so core to the workflow that it felt very worth it to me to spend a little bit of extra time to get to a deeper level of comfort with it, and I have not regretted one minute of that. Vim and tmux are pretty similar because they're such core tools for me. But React, I would not call myself a deep expert of React. I follow some of the changes that are happening but not as deeply, and I'm not as worried about it. And if I'm like, I don't know how to do this thing, should I spend two hours learning about it or not? With frameworks and tools that have not been part of my toolset for as long, I will spend less time on them. And I think that the courses that I produced on Upcase mirror that. They're the things that I'm like; I feel very true about these things versus other stuff. Maybe it was in a weekly iteration episode or something like that. But that very much mirrors how I think about learning as well. What are the things that I'm going to continually invest in versus what are the things that I'll sort of keep an eye on from a distance but not necessarily invest as much time in? STEPH: There's a particular article that you're making me think of as we're talking about content creation and, as you mentioned, finding the things that you always find value in investing in. There's a wonderful blog post that was recently posted on the thoughtbot blog by Matheus Richard, and it's called The Opportunity Will Find You. And it made me think a lot about what you're talking about, find the things that you're excited about, find the things that you think are a good investment and just go ahead and lean into it. And it's okay if maybe that's not the thing that you're using currently at your work, but if it's something that gets you excited, then go ahead and pursue that. So in this article, for example, Matheus uses the example of learning Rust, and that's something that he's very excited about and wants to learn more about. And then there's another one where he started looking into crafting interpreters. And then that has actually led to then some fruitful work around creating custom RuboCops because then he had more knowledge around how the code is being interpreted so then he could write custom RuboCops. So yeah, plus-one to finding the things that give you energy and joy and leaning into that and investing in it. And if you share it with the world, that's fabulous, and if you don't, then keep it for yourself and enjoy it, whatever makes you happy. On that note, shall we wrap up? CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Steph celebrates Utah's adoption day and Daylight Savings Time and troubleshoots a CI build time that had suddenly spiked for a client project using TeamCity. She also shares a minor update regarding the work that thoughtbot is doing to scale horizontally and add more machines quickly and efficiently to process more RSpec tests. Chris was alarmed by logs and unknown-unknowns and had some fun using Git down. Git bless his heart! This episode is brought to you by ScoutAPM (https://scoutapm.com/bikeshed). Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. TeamCity (https://www.jetbrains.com/teamcity/) lograge (https://github.com/roidrage/lograge) Cleaning up local git branches deleted on a remote (https://www.erikschierboom.com/2020/02/17/cleaning-up-local-git-branches-deleted-on-a-remote/) Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris. Today is Utah's adoption day. So officially, one year ago, we adopted Utah. He's about a year and a half years old now because we got him when he was around the six-month mark. So Utah, aka Raptor, which is the nickname that you gave him, and aka UD [spelling] the cutie is his other nickname...which I've forgotten, why do you call him Raptor? Why is that a name? CHRIS: Because there's a Utah Raptor. STEPH: A person? [laughs] CHRIS: No, I think it was like the fossils were found in Utah. But the Utah Raptor is a type of dinosaur. And so when I heard Utah, my brain went to Raptor, and then I dropped the Utah sort of a Cockney rhyming slang sort of thing. Shout out to Matt Sumner real quick. But yeah, Raptor. STEPH: Cool. Cool. Cool. I'm so glad I asked. Now I know. I just accepted it when you called him Raptor. I was like, sure, he can be a Raptor. [laughs] CHRIS: I feel like that says a lot about me that you were just like, okay, why not? STEPH: [laughs] CHRIS: That's different and has no apparent connection to the actual name of the creature, but that's fine. I might be a nonsense person. STEPH: Or me for accepting it. You share a lot of nonsense, and I accept a lot of nonsense. That might be our dynamic. [laughs] So it works out. CHRIS: That just may be our dynamic. STEPH: That's why I'm always so nice with the good idea, bad idea, or even terrible. [laughs] CHRIS: You're like, it's all nonsense 100% of the time, but yeah. So Utah is one year into living with you folks. So that's lovely. STEPH: Yeah, and he's growing up so well. Oh, and I've been training him for one of his latest tricks. I'm very excited because it seems to be really sinking in. So every night, we take him out for his final bathroom potty but then before we go to bed. And one night, for some reason, I started singing The Final Countdown. [singing] It's the final countdown. But I started singing it's the final potty instead. So now, when it's time to go out for the bathroom late at night, I look at him, and I start singing. And I start singing [vocalization], and it's working. He's starting to recognize that when I started singing that tune, he's like, okay, and he gets up from his comfy spot, and we go outside. And it brings me a lot of joy. CHRIS: That is perhaps the best use of Pavlovian conditioning that I've ever heard of. Also, I really appreciate that you both mentioned the final countdown but then said just in case anyone is unfamiliar with the tune, let me hum a few bars. Thank you for doing the service there. STEPH: I have been singing so much this week. I don't know if Joël Quenneville, who I've been pairing with a lot, appreciates that. Sorry, Joël. But I have been singing so much. And I think that's post-vacation vibes. That's what vacation does for you. And it helps you get back into, you know, lots of singing or at least it does for me. Let's see, what else is going on this week? So this is the week that we have DST in the USA, so Daylight Savings Time, aka summertime, where we advance our clocks so everybody...although this is going to be late. So at this point, by the time people are hearing this, you're going to have already dealt with all those bugs that have crept up. But those are creeping up this week, where people are starting to notice a lot of those flaky specs that aren't technically flaky. They're actually breaking for real reasons because they were tested in a way that shows that they're not considering that daytime boundary. CHRIS: It's as if you spend some of your time fixing flaky specs that that's where your mind goes with DST. Because I'm going, to be honest, part of what you're doing right now is telling me that this is coming up, and I didn't know. I had forgotten about that, which is very exciting, except you lose an hour asleep for this one, right? Or is it that you gain? STEPH: We're going forward. Yeah, it's fall back and then spring forward. That's how I remember it. CHRIS: Worth it. I'll take the sunshine at night. STEPH: Yeah, it's supposed to be so we have more sunshine during the daylight hours. That's the reasoning for the nonsense, the headaches. On some more technical news, when I came back from vacation, we noticed that the CI build time has suddenly spiked for the client project where previously we were averaging, I'd say, around 25-26 minutes. There's definitely a range there. But that seems to be pretty consistent. And right now, builds are taking more about 35, sometimes upwards to 45 minutes. And so it's been a bit of who done it or what caused it adventure of figuring out why, what's causing the spike. And so Joël and I have been pairing heavily on that to investigate what's going on and learned a lot of features that TeamCity offers and just diving into this particular issue. One thing that brought me joy is by looking through all the builds that are taking place on TeamCity. As I noticed, there are a number of builds that are using the RSpec selective testing that I added where if you only change a test to then we're only going to run those tests instead of the whole suite. And it was one of those changes where I thought, okay, maybe someone's going to get use out of this. Joël and I will probably get use out of this. But I'm actually seeing it about one every ten build something like that. And I'm just like, oh, this is awesome. One, people are improving tests. That's amazing. And then two, that then they're benefiting especially while we have this spike going on. So that was a suggestion from you that I appreciate because that is paying dividends. And so that brought me a lot of joy while looking into this other issue, which we haven't resolved yet. We think it has something to do with how the tests are being balanced across all the different parallelized processes. And we think that there is an imbalance that has happened. And then that's what's really throwing things off. So we can see that one particular process is taking around 26-27 minutes, but then the next process that's highest in time is only taking 17 minutes. So it's like, why is there suddenly ten more minutes that's being attributed to one process? And why is that not getting spread out? So still looking into that. That's the mystery for this week. But that's mostly what's going on in my world. What's up in your world? CHRIS: What is up in my world? I'm going to say a quite alarming thing happened this week, which was we were investigating some changes, or we were investigating some behavior where the particular portion of the system ended up in the logs, just sort of combing through. And I happened to notice this one log line that...our logs tend to be somewhat verbose. They're JSON-structured log format. I've talked about the lograge setup that we use in the past, but there's a bunch. These are long lines of JSON-structured data. But this line that caught my eye was not. It was just some text, and it said, "Unreported event: and then some other texts." And I was like, ah, what? Who didn't report which to when? I did some digging, eventually figured out that this was Sentry. Sentry was logging that it had not reported an event to us. But had we not randomly happened upon this in the logs, which is sort of a random thing to see, we would have missed this, which is scary. I mean, it was missed for a little while. And so Sentry was not reporting certain events. We had made a change, particularly to Sentry's before_send configuration. So there's a way that you can do some amount of filtering client-side or client being, in this case, our Ruby app. So that's like the client-side of Sentry, and then there's their server backend. So that would, weirdly, that's the way the client-server work in this case. But the idea is you can do some proactive filtering of being like, you know what? Rather than sending a ton of noise...because we know there's this one error that we can't stop for reasons. It's a JavaScript Chrome extension that's getting embedded in the app. That doesn't mean anything; that's just noise. Rather than even sending those over to Sentry, let's proactively filter them out. before_send is a function within the Sentry SDK that allows you to do this. But it turns out if you raise an error in there, if you happen to have introduced something that doesn't cover all the possible edge cases, then Sentry will just not let you know and will log, interestingly, that they did not report the event. I'm going to throw it out there that I would love if Sentry were to say Sentry me...that's where I put something very bad happened, and you should look at it. And they're just like, well, something pretty darn bad happened. We'll log it. Supposedly, my understanding is before_send can be used to filter out like PII or other things like that. And so their failure mode is quiet intentionally. That's my understanding as to maybe why this is true. I wish there were configuration that said, no, please fail as loudly as humanly possible. But that was terrifying. STEPH: Yeah, absolutely. I'm going to piggyback on what you just said for a minute because I was also thinking earlier and related to the sudden spike in our CI builds where I was like, it would be really nice if there's...because I suspect there's one particular change that has caused this to happen. I don't know what it is yet, but that's just my suspicion. And it would be great if when that build ran, let's say that build went from an average of 25 minutes and suddenly we have a build that took 35 minutes if TeamCity had alerted us or if something more aggressive had to happen to say like, "Hey, your team..." or maybe it's just in the logs somewhere. Okay, not in the logs somewhere more visible on the build where it's like, "Hey, your build took an extra 10 minutes compared to the average, just letting you know. I don't have a diagnosis for you, but we're just letting you know." So yeah, plus-one to getting those types of alerts out to people and notifying us when there's an average that's not being met or when things aren't getting logged like you'd expect them to. CHRIS: As part of what we were doing in the logs...like how to get to that anomaly detection place is a really interesting question in my mind. And this is a case where we were in the logs, and we wanted to instrument more things. So we have a bunch of stuff right now that goes in. It's either a warn or error log level. And the error should be pretty rare because, ideally, those are going to Sentry instead, but we still want to keep an eye on them. But we introduced a new search within log entries, which is what we're using for logging aggregation and searching. And the idea was to group all warn-level messages and to group it on the message string. So ideally, what this allows us to do is say, "Oh, we've seen 200 instances in the past two days of this new warning that we didn't see before." The difficulty is, as a human, I would see unhandled error blah as one bucket of warning, or I might want to see it that way. I might want to group it on part of the message. So it becomes really hard to find the signal in the noise on these, but at least it was a start. We now have this little graph for both warning and error-level log messages that we can see are there any new anomalies that are occurring pretty regularly? But this, again, was just this weird edge case where we were lucky to catch it. But it was very scary that it was just throwing stuff away. So the universe might have been true that our error log did get a little quiet for a little while, which was nice, but it wasn't 100%. It wasn't like we were at 10 hours, an hour, and then we went to zero. It was like some, and then we went to a lower number because we were still getting some. We were only filtering out certain ones. But yeah, it's how do you know at runtime that the system is doing the thing? This is increasingly the question that I have in my mind. But yeah, so that was the thing. We fixed it. It's fixed now. I also set up an alert in log entries to say, "If you ever see this particular phrase again unhandled or unreported," then please tell me about that post-haste. So we've got that now. STEPH: That's perfect. That's what I was about to ask us if there's a way that you could add a filter or add a warning for that anomaly detection. So that sounds great. CHRIS: I've got that now because this became a known-unknown, but there are still the unknown-unknowns, and there are so many of them. And I can't know them is my understanding of how they work. I would love to know them. I would love to pin them down and be like, "Hey, what are you doing here?" Someday maybe. But anyway, that was the thing in my world. [laughs] It was fun. It was a great little time. What else is up in your world? STEPH: I feel like you can always judge the level of fun based on how high someone's voice goes. No, it was fun. It was great. It was fun. [laughter] CHRIS: I believe that is an accurate assessment, yes. STEPH: I've caught myself doing that. I'm like, my voice is extra high, so I don't think I really mean that when I'm using the word fun. [laughs] Mid-roll Ad Hi, friends, and now a quick break to hear from today's sponsor, Scout APM. Scout APM is an application performance monitoring tool that's designed to help developers find and fix performance issues quickly. With an intuitive user interface, Scout will tie bottlenecks to source code, so you can quickly pinpoint and resolve performance abnormalities like N+1 queries, slow database queries, and memory bloat. Scout also recently implemented external service monitoring, adding even more granularity when it comes to HTTP requests and API calls. So give Scout a try today with a free 14-day trial and experience first-hand why developers worldwide call Scout their best friend. And as an added bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. To learn more, visit scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. I do have a small update that I can share regarding the work that we're doing to be able to scale horizontally. So we want to be able to add more machines quickly and easily so we can then process more RSpec tests. And we have discovered with TeamCity that we're pushing forward on that particular path because they have something called a composite build. And with a composite build, it's essentially your parent or your supervisor build. And then, from there, you can create other subsequent builds. So we can then say, all right, let's have multiple builds that then run the RSpec test, and then we can separate in that way. And right now, we're going about it in the hacky way because we just want a proof of concept. So we are saying specifically in this particular step, we want you to run spec models. And in this other process, we want you to run these particular tests just because we want to see how this works. And so far, the aggregation seemed great. So when you look at that composite parent build, it's showing you how each of those builds are doing. It's also reporting back the failures. It's even de-duping them. Because initially, we set it up where we were running the full test suite in parallel on both of these builds, [laughs] not what we wanted, fixed that. But it did highlight that it was de-duping the test failures. So that part was nice. So the UI seems great and seems quite very capable of doing this. Composite build seems to be the way that we can do this with TeamCity. But we're still diving into actually getting the metrics like, okay, how much is this actually going to speed us up? And what does this look like if we want to be able to scale up to say from 5 to 10 where we went from 5 machines to 10 machines? And that part doesn't feel graceful because then you have to go in and change the configuration and copy the configuration to then add a new build that then is going to process RSpec test. So other services like Buildkite make it very easy. I can't remember if it's like literally a slider or if it's a number that you enter. But you can say, "This is how many processes that I want to run," in which it would be a lot nicer for that actual scaling. Versus TeamCity, it feels far more manual and intentional where you then have to duplicate and add those settings. But it's a really good first step because, as we'd highlighted before, there's a lot of risk in moving over from an existing infrastructure to something totally new. So if we can have some wins with this approach and help out the team and reduce build time, then that gives us more grace period. So then we can assess, okay, do we really want to move over to Buildkite? What do we want to do next? What does this look like? And have further discussions. So that's a small update there. Next time I should have some more updates around actual data on how things are looking. CHRIS: Oh, cool. Yeah, I appreciate the update and definitely interested to hear how this continues to play out. This is a large project that you're undertaking and all the facets and whatnot, so yeah, super interested to hear the continued journey of the test build time reduction. Let's see, other news in my world. I've been exploring something that I'm intrigued by the idea. Let's go with that. [chuckles] That's going to be my start. I always start with these lead-ins that build things up too much. But I am finding a small tension in trying to just keep up with what the team is doing, which is a wonderful place to be. Our team is growing. We actually have someone new joining tomorrow, very exciting. But I'm trying to find the right version of I don't want to block things. I don't want all code review to have to go through me. But I do want to keep an eye on everything. I want to kind of know what we're doing collectively. And ideally, mostly, that's me being like, yep, that makes sense. We're doing that. I remember that, cool. Wait, what's this? And rarely, occasionally, there'll be a point where I'm like, oh, I want to intervene here. I want to have a conversation. I want to rethink how we're building this. And so it's moving from a place of any sort of blocking synchronous review or the necessity for that to ad hoc post-review sort of thing. And so the way that I'm trying to poke around with this, of course, I'm writing some code to do it because of me. So the two systems that we're using that seem most of interest are GitHub and Trello. And so it turns out GitHub has a wonderful search, and I can create a search that is parameterized like create a URL that jumps into a parameterized search saying, "Show me everything that was merged in the past X amount of time, " so I can say the past two days because I haven't checked it in two days. So I'll see all of the PRs that were merged, and some of them I'll have already reviewed. So I maybe could even filter further there. But for anything that I haven't seen, I'm like, oh, what was this? What was that? What was this other change? Similarly, on Trello, there's a way via the API to get all of the card update actions. And then I can filter down to say whenever a card was moved, which in our system that means...we're doing Kanban-style, so a card being moved from this column to that column that tells me that someone is progressing forward with some work. And then I can further filter down because, again, I don't really want to be blocking on this. I'm most interested in what have we done or completed in the most recent timeframe. And thus far, it's an interesting data set. And it's an interesting way to switch the problem around such that I'm not feeling...there was FOMO or organizational FOMO is perhaps how I would describe it of like, I want to try and keep an eye on stuff and make sure I'm responsive. But I'm now blocking, so I have to step away. But now I'm worried that I'm missing things. And so I'm trying to find that good middle spot. And this feels like an interesting exploration of that. STEPH: I'm intrigued when you mentioned the card moving over, so then you can tell things are progressing. And then you're answering the question of what did we do in this particular chunk of time? When you move stuff over, is there a clear sweep of we have finished this sprint, and then you have the date of that sprint at the top, and so then you essentially have a column that represents all the work that was done in that sprint? Is that an approach that you're using? Because that's the one that immediately came to mind for me when you're wondering what was accomplished during this week or two-week period? CHRIS: Interesting question. So we're not really doing sprints, or there are no real iterations. We're doing more of the I think Kanban is the way to describe it. But basically, we have a prioritized next up column. And then every day, I can say continuously, the work has the same shape, which is pick up the next most important thing, work on it, move it through the various columns. I did introduce in Trello just the idea of, like, here's a month, so we can see by month what we're doing, but that's too low granularity in my mind. I want to review it a month at a time. The whole point of this in my mind is to see stuff as it's happening vaguely in real-time but not requiring me to constantly be monitoring everything. So it gives me an opportunity at the end of the day to be like, what happened today? What do we do? But yeah, so there's no real sprint that I would couple this to because we're not really doing sprints. STEPH: Got it. Yeah, that gives me more context. I understand why you're then looking for ways as to how to answer that question of, like, what did we accomplish in this week or a particular time period? CHRIS: And to name it, this is not an intention on my part to be like, I need to control everything. I need to make all the decisions. I very much want to empower the team. And in my mind, this is actually a mechanism to empower the team. I want to give them more freedom and then have the opportunity occasionally to check back in and be like, oh, actually, there was some context that was missing here the way we did this. Let's actually unwind that, do it this other way for these reasons. But it gives me the ability to potentially have that conversation after the fact. We're trying very hard to have the tickets be as representative and complete, and well documented as possible. But that's very difficult to get to. And there are also things that I don't even know to mention. Again, I think the critical bit is this is not an attempt to make sure everything aligns with what I think; it's more I want to empower the team to move without me most of the time. And then, where there are things that potentially should have a small conversation or a redirection, then we have the ability to do that. And so, I'm trying to build that back into my workflow while basically loosening up my connection to the work in progress at any given point in time. STEPH: So you just touched on a topic that's really interesting to me or a particular space. You're doing a very kind thing where you want tickets to have lots of context so that people feel confident when they're picking up what's the action item to be done. And for someone that's new, that's incredibly helpful, and I think more important since they are new to that world. But in general, my spicy take of the moment is going to be as developers; that's part of our job. If we notice that context is missing or if we're not clear about the action item, is to think through what is it that I'm missing? Who do I reach out to? Who can I go to for help? How can I scope this work? All of that, to me, is very much part of our role. And the idea that tickets always have to be perfectly curated, which I don't think you're saying, but you're just trying to be extra helpful. But if someone were to have that expectation, I think that expectation is wrong. And I do think it is part of our work that then we help make sure that tickets are well-scoped and well-defined and have those conversations with the people creating the tickets or creating them ourselves. CHRIS: I love the clarification there, and I'm definitely in agreement with you. I don't know how picante of a take it is. I would be intrigued. Listeners, let us know. Are we breaking your mold of what things should be? But I do like the idea that it is a conversation so back and forth. And so the idea that as developers, there should just be this very clear list of things to do and you just kind of pick up a card and heads down, just get it done, I don't think that should be the mold. But I do think; ideally, the why is the most important thing that I think should be in a card. So ideally, a card should have little in terms of technical implementation notes and should have more in terms of here's the goal that we're going for, here's the problem, or here's the thing that we're trying to solve. And then maybe a suggestion of like, I think it could be an X, Y, and Z, but I'm not sure. Or we want to be able to send transactional emails, but I don't know any more than that. Our goal is to engage users. Like that last sentence, that last little bit of our goal is to engage users is a critical, critical data point, versus our goal is to solve for a regulatory and compliance issue. It's like, well, those are different. And they will lead to different solutions and different implementations and all that. So yeah, I definitely share the idea that cards don't need to be perfectly specified. And if anything, I think I'm closer to that than it probably sounded like I was. But for that reason, it's totally possible in my mind, that work will be done in a way that after the fact, I'm like, "Oh, sorry, there was a misunderstanding here. Let's revisit this work." And so, my goal is to try and stay connected and have a feedback mechanism at the end of the process. So when the work is done, be able to spot-check it rather than trying to have to watch it as it's happening or proactively define everything in excruciating detail such that exactly the right things happen all the time. So I'm moving to a place of ask forgiveness, not permission. That's the wrong analogy here. But that idea of like, we can clean it up after the fact, that's fine. And we don't need to try and prevent any sort of things, or at least that's what I'm exploring. STEPH: Yeah, I love that you highlighted having the why. I adore that when that's on a card just because I then I want to know the goal because then that's going to help me ask questions and think about scoping versus if it's like a very specific implementation, then I feel so narrowly scoped that I don't feel as confident that I can be like, okay, I know why I'm doing this versus I just feel very directed to do a thing, and that's incredibly helpful. I have also felt the pain that you're mentioning where it does feel like a ticket has all of the work clearly defined, and the goals, and the whys, and it can have everything there, but just something gets lost in the communication. And so someone implements something in a way that is how they interpreted the work versus it's not actually what the ticket or what the goal of the work was to be done. So I appreciate that where you are looking for ways to tweak things to make sure that whoever is picking up that ticket will have the same interpretation that the author intended for them to have. And then if that does happen, and things get misaligned, then you chat and figure out ways to improve it. I think that's the point that I was really thinking about, and my air quotes, "hot take," is that as developers, a big part of our job is communication, and then also sharing the knowledge that we have with other people. And so if someone is expecting that they can just always pick up work and never talk to someone, I don't know, maybe you're in the wrong business. [laughs] That's my hot take. CHRIS: I, for one, like the hot take. It is nice and ever so slightly spicy. STEPH: Thanks. Yeah, I just think communication is incredibly important. Earlier, you mentioned, I don't think we were on mic at the moment, but you mentioned something about a new Git alias. And I am very intrigued on hearing about what you've added, what it does, all the details. CHRIS: All the details, that's probably too many, but some of the details I can certainly provide. So I have two new Git aliases; one is Git gone, which is probably the heart of the whole thing. And so the background of this is I found myself pushing the green merge button on GitHub more. We've introduced some branch protection stuff, which I've talked about in previous episodes. And I dream of the day that one of my good, good friends at GitHub will give me access to the merge queue beta. Please, please, I implore thee. But in the interim, still clicking the green merge button more often than not. STEPH: Wait. I have to ask to help you in this dream. Are you forwarding these episodes to someone? You can just take a clip of you saying, "Please, please, please give me access," [chuckles] and just forwarding that or mentioning someone at GitHub or GitHub in general. CHRIS: Just leaving voicemails for people with a Bike Shed section of me begging for access to the merge queue beta? STEPH: Yeah. [laughs] CHRIS: No, I'm not. But maybe I need to up my game. You're right. [laughs] Someday, I'll get there. And that will only exacerbate this issue that I'm feeling, which is again, I'm clicking the merge button. That's what's happening. And as a result, that means my local branch is now like it's done its job. You've served me well. And in the Marie Kondo sense, I need to hold you up, thank you for your service, and then let you go. But I obviously wanted to automate that. So Git gone does that automation, and it was fun. So I found a blog post which we'll include in the show notes, that had most of the pieces here, but it was still fun to play with the shell pipeline in a way that I hadn't in a while. So it does a Git fetch and then git-for-each-ref with a particular structured format that references the upstream of the branch then uses awk to search for the word gone. Because Git, if you print it out in this particular way using this format, it will say the local branch name and then the upstream. But if you've deleted the upstream, it will specifically say (gone) in brackets, so you can actually use that to filter them down. And then I pipe that to git branch-D so..well, xargs of course. I love a little shell pipeline. As an aside, these are fun little things to build up. So that is Git gone. And then the other one that I have is Git down, which is what I use more. And Git down works on top of Git gone, so it's Git checkout main and and Git pull and and Git gone. But that means I get to type Git down into my terminal whenever a branch happens to get merged in the upstream land. [laughs] STEPH: [laughs] Oh, that's adorable. I love it. I like the Git gone, and yeah, I like the Git down just for fun. You are inspiring me where I now really want a Git bless your heart that's like maybe a Git blame or a Git revert. [laughs] CHRIS: I've definitely seen people do Git praise as an alias for Git blame. STEPH: That's nice. CHRIS: But Git bless your heart is...ooh, I love that. STEPH: [laughs] I might have to add that just so I can type it, and then someone can say, "What are you doing?" [laughs] Cool, I love it. CHRIS: Little things, little fun bits to add to your day and to automate and have a little fun while you're at it. So that's where I'm at. STEPH: All about the communication and fun. That's what I'm here for and the singing. Let's not forget the singing. CHRIS: And the singing, of course. STEPH: [singing] On that note, shall we wrap up? CHRIS: Let's shall. Oh. STEPH: [laughs] CHRIS: The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Bye. ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Steph is excited to be headed on a retreat with her mom in the mountains, but before that, she details how she helped troubleshoot a production issue with her team and appreciated their process. She's also looking into tooling around spinning up more machines to process more RSpec tests. Chris had a developer start their new job at Sagewell and highlights how they involved the new person in rectifying potentially missing and/or confusing existing documentation. He also has a gripe, and that is accounts. Handling too many accounts. Additionally, he talks about triaging an error and how it was tough initially to understand if something was actually broken. And then it was even harder to understand what was broken. So he paired through it and used the power of putting two heads together. This episode is brought to you by ScoutAPM (https://scoutapm.com/bikeshed). Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: CHRIS: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris, I am going on vacation next week, and I am so excited about that. It's going to be pretty much a week long. It's like a Tuesday through Friday ordeal. And it's a trip that I'm taking with my mom. So over the past year, she's gotten super serious about her health and nutrition and done a phenomenal job of being very focused on a plant-based diet, which is basically healthy vegan food is what that comes down to. So there is a retreat that's taking place in the North Carolina Mountains that she's really excited about. I'm going to go with her. We're going to do lots of cooking, and hiking, and hanging out in the mountains, and it's going to be lovely. CHRIS: Well, that does sound lovely. STEPH: Yeah, it seems like a really perfect time to disconnect just because you're headed into the mountains. So all you should take with you are books and things that are not iPhones, and tablets, and computers, and screens. So I'm looking forward to that, just to be away from screens for the week. On some more technical news, this past week, I helped troubleshoot a production issue, which was a bit novel for me because the work that Joël and I are doing with our current project it's all in the testing realm. And so it was probably around 10:00 o'clock at night my time, and I got a ping on Slack. And it looked like I was getting called in for a production issue. And I was like, I have touched zero production code. [laughs] So I'm very intrigued how I could have broken production at this point. And so I looked into it, and it turned out that it wasn't necessarily related to a commit that I had authored, but it was for a commit that I had reviewed and then approved. And so their strategy is they create a new channel. They'd gotten a ticket that an error was occurring. And then the site reliability team created a new Slack channel, and then they pinged everybody who either authored, reviewed, and approved that change to be like, hey, we think the issue is related to this commit. Our plan is we'd like to roll it back. But before we do, we just want to check in with folks who have more knowledge to help us confirm that, yes, this error message seems related. And I really liked that approach. I really like the idea that it's not just the person who merged the commit that then gets pinged on it, but it's like everybody else who happened to look at this and review it come help us too. So we spent some time looking into it, confirmed that yes, indeed, it was related to that particular commit. And then their team did the wonderful thing of then rolling it back. So then, it was no longer an escalated issue. And so then I asked, "What else can I do to help?" And they said, "Well, from here, it's no longer a production issue. So tomorrow, just follow up with the author and let them know and issue a fix for the bug, and then merge it like normal." So we're back in that normal pull-request flow, very calm. And overall, I just appreciated their process. I like very much how they pulled more people in because I think some of the other people that were involved weren't online, which makes sense because it was really late. So that way, you just spread in case some other people really aren't available that then hopefully you'll get lucky and one of those three or four people are available to help you troubleshoot. CHRIS: That does sound like a really nice and thoughtful and intentional bug response, communication, procedure, rollback, et cetera. All of that sounds like it worked very well and is nice to have. And it's the sort of thing that a larger organization ideally gets to, having these sorts of processes. Spoiler alert, later in the episode, I will talk about the other side of it of being a very young organization and trying to be like, wait, is this a bug? Is this not a bug? Should we roll back? What do we do? That's actually my topic de jour. But what you're describing sounds like the calm even in the case that there is a fire sort of like, yep, we've got procedures. We have workflows. We have communication channels and ways that even the exceptional things can be handled in an ideally as calm as possible way. So that's awesome that that's what you got to experience there. STEPH: Yeah, getting called in at 10:00 o'clock is never fun for anybody. But when it happens, because it's going to happen, then I appreciate the thoughtfulness and that process that they put behind it. So it all went fairly smoothly. And it was also one of those fun things where I haven't met...like this is a very big organization, so I hadn't met any of those people. So when I got pinged on it, and then I hopped in, I was like, hi, I don't know anything about this process and what y'all are doing, but I am here. I'm here to help. Where can I look? What can I do? So it was also a fun endeavor in that regard to just be like, I don't know what I'm doing, but I am here to help. Please let me know how I can help. And it ended up working pretty well. So yeah, that's been a fun adventure for this week. How about you? What's new in your world? CHRIS: What is new in my world? Well, we had a developer start this week, which has been really wonderful. Unfortunately, we had scheduled their first day to be Monday, which was Presidents' Day, and that's a holiday. So we got out in front of that one and figured it out. We're like, no, no, actually, feel free to start on Tuesday. We'll not be around on Monday, so you shouldn't be around on Monday. But then, on Tuesday, they started. And we intentionally structured things such that we have a contractor that has been working with us for like seven or eight months now. So it's been a long time and been very formative as well the work with that contractor. So this is their last week, and thus, we very purposefully brought the new person on the team and that contractor together to maximize the amount of pairing and overlap that we have there just to try and as intentionally as possible grab whatever is in their head, get another point of view. Because this new individual on the team will be able to work with myself and the other full-time developer on the team a bunch moving forward, so we want to maximize their overlap with the person who is on their way out. But otherwise, it's been great. We're a young organization, so the version of onboarding it's me running around setting up a lot of accounts, forgetting to set up other ones, getting pings in Slack, and then following up and setting up another account. Eventually, I hope that there are checklists and formalizations and, ideally, one-click SSO magic that makes all of that work. But for now, I'm happy to chase it down. But really, we're just leveraging pairing as much as possible as the onboarding tool to make sure that where we don't have formalization, procedures, documentation, et cetera, as thoroughly built out as I would love to be at, we can shore that up with some time with other humans. STEPH: That's awesome. It's always fun having someone new to join to highlight all the things you need to automate or at least have a checklist for to then help them onboard. But that's really exciting that you've got a new teammate. CHRIS: Yeah, definitely very exciting. And they've been great. They've hit the ground running and a couple of pull requests already and just contributing very effectively within their first couple of days. So that's always wonderful to see. We are definitely taking this moment to document what is undocumented or update the README where it needs to be and start to make that checklist. We have another person who will be starting in about two weeks' time. And so, ideally, that will be even a little bit more fleshed out of a process. So slowly, incrementally get a little bit better with each we add that we get there. STEPH: How much do you involve the new person in creating that documentation? Is that something that you ask them to help build, or is it something you take ownership of? What's that balance? CHRIS: It's interesting. So definitely some I want to be with that person because I think it can often be the easy first PR is an update to the README for like, oh, I tried to set up the app, and it did not work. For this reason, I have now updated the README, and now there's a pull request. And we get to experience that flow via the very low-stakes change of updating the README. So that's a definite one that I like to have. The other is I'll typically ask for the individual to capture as much as possible. There's a very delicate line in my mind between empowering them and being like, yes, absolutely. We're young. We don't have everything documented. So feel free to make changes where that makes sense to you. But at the same time, I know that joining a new team can be complicated, can be intimidating in certain ways. You're not sure what's okay to change? What's not okay to change? That sort of thing. So I simultaneously don't want to put the pressure on someone to be like, "Yeah, no, change anything you want. Literally, nothing is stable here. Nothing's glued to the ground. So feel free to pick up anything and throw it out the window." That feels too far in my mind. So I don't have an actual answer like, I'm ideally calibrated at this point. But it's sort of those two tensions that I'm holding in mind as I think about that. STEPH: Well, I really like your answer. I like that balance because I think it's really nice to include the person in those changes and also just because they're going through it. So they happen to have that insight, and it's fresh. But I agree, when you're joining a job, you want some stability and confidence that the people that you are joining that team with are also working hard to make it a very positive onboarding experience. And if you just were to push all of that responsibility on to them to be like, "Yeah, we know. We don't have this organized yet. So you tell us everything that we need to do," that would feel unkind to that new person. I think as a new person that I wouldn't fully enjoy that. I don't mind some of it, but I wouldn't want all of it. I'd have nervousness around ownership, around improving processes, and who that belongs with. CHRIS: Sort of a classic case of it depends, or it's a little from Column A, a little from Column B, but definitely some, just hopefully not too much. STEPH: The Goldilocks of onboarding, some onboarding responsibilities, but not all of them, just the right amount. [laughs] CHRIS: Shifting gears slightly, though, I just want to gripe for a minute. I'm just going to gripe. This is not my normal mode, but I'm going to lean into it. STEPH: Do it. CHRIS: Accounts, just accounts. I have so many accounts now. There are so many across different systems, and I'm trying to do the good thing, which is let's stop using personal accounts for anything and only use organizational accounts for the things that are for work. And some organizations do a great job with this. GitHub, I'm looking at you; really well done, super happy with the way that you folks have implemented accounts. You get that I am one human being that contains multitudes. I am my personal self; I am my work self. I am maybe even another version of work, and you get that. And you usually let me exist as all of those versions of myself and, man, do I appreciate that. Heroku, you're okay. Like, it's all right. You treat the different facets of me as different accounts, but that's okay. You make it relatively easy to switch between. Although you do make me two-factor auth and re-login every single day, and I don't love that. So I don't know what's going on there, but fine. Trello, aka Atlassian, I guess at this point, come on, what are we doing? What's going on here? So originally, I had started, and I had the one Trello account, and I had my personal boards. And then there was the Sagewell organizational account. And within that, there were some boards, and I would just bounce back and forth. But I realized, no, I need to do the right thing. So I created a new Trello account. And now Atlassian just forces me to switch between them, and it loses the link that I'm going to often. It's a different login interstitial screen. And it constantly shows me that like, hey, you don't have access to this. Do you want to switch accounts? And I say yes. And then they take me to a screen where I can pick between two options, the one that I was that didn't have the ability to do it and another. And as a developer, I know that the thing I'm about to say is not fair. But come on, folks, you could know the answer to this question. There are two, and one is the wrong answer, so the other one is probably the right answer. You don't need to autolog me into that; I get it. Just emphasize it because they almost look identical on the list. I have now accidentally tried to request access with my secondary account to my other account, and I can't get out of that state. So now, one of the ways that I try and do this it shows me a list of them to pick. The other it says, "You have requested access. We're waiting to hear back." And I'm like, no. So anyway, that's a thing. STEPH: So I know people can't see me. [laughs] So I'll narrate that I'm dying over here because I very much appreciate that we are positive people. We are very focused on bringing positive energy, but the descent into the amount of shade that you're throwing at different applications [laughter] just really made my day, and I feel that pain. I have felt that pain with Atlassian and can relate. And we should have some gripe sessions. This feels healthy. This feels very...okay, well, I don't know for you. I'm the one that's laughing and getting joy out of this. I don't know if it's helpful for you, but it feels very cathartic to me. [laughs] CHRIS: It is definitely somewhat cathartic. I think there's utility in having these sorts of conversations. And throwing shade at Atlassian, whatever, they're doing fine, so I'm not super worried about it. But generally, we try and keep things positive because I think that's, frankly, a more effective way to communicate. But occasionally, it is useful to look at the things where I'm like; that is a pattern that I do not want to repeat. And I'm sure that there are complex organizational enterprise-y reasons that it has to be this way. But I can look at that and say never that. That experience as a user is like, wow, yeah, I just tripped over nine layers of your enterprise there just trying to do very simple day-to-day things for myself. So I want to avoid that. I've griped about that one login, not the company OneLogin. But that one login page that I've experienced where I start to interact with the form, and suddenly some JWT handshake in the background happens, and I'm now logged in. And it just rips the page out from underneath me. That is unacceptable. That is not okay. And I really do think there's something worth occasionally looking at those and being like, well, not that. But anyway, I should probably stop my gripe session now. STEPH: [laughs] Well, if I may join in, I have one that I'd like to share. Since we're on this -- CHRIS: Throw it on the pile. What else we got? [laughs] STEPH: [laughs] So there was some code. There was a piece of code that I was looking at that was very not friendly. It was difficult to understand. It took a while to parse through what are they actually doing? What records are they creating? Why did they choose this manner? Why are we iterating over these particular numbers? What's the outcome here? And I was pairing with Joël and was going back and forth having a conversation trying to be the detectives of why this code exists, and we finally got there. And we finally understood what it's doing and why. And I just lost it for a minute once we finally got there. [laughs] I just thought the way this code is written, it does not improve readability, and it doesn't improve performance. All it did was make my life harder because it was very difficult to read. So all they did was become really clever with the code that they were writing and essentially drying it up, which I have such a beef with DRY because it has caused me pain. And so they essentially were drying up their code or introducing a way to make it just take up fewer lines that took up less vertical space. But overall, I was very grumpy about it. And Joël was very kind about it and was like, "Well, this is the type of code I could see maybe why they did this." But you're right; it doesn't help with readability and performance. And he was helping balance out my grumpy goose moment. I've been having a lot this week; maybe it's just the week I'm in. I'm in more of a fiery mode this week [laughs] with some of the code that I'm seeing, and that was one of them. That was the please, please, please don't DRY up your code. If it doesn't improve readability or performance, there's just no need. There is no benefit. CHRIS: Well, I definitely know that feeling. And I think I've probably, as a developer, gone through that arc where early on I was just trying to make stuff work, and then I learned how to be clever. And suddenly, being clever became a game that I could play. And then, pretty early on, I realized I would come back to my own code from two weeks ago and be like, what the heck does this do? I have no idea. And that's when I was drawn to Ruby. That was one of the things. I'm like, oh, I can write code that looks so much like the clear words that I have in my head about the thing. I like that. And so much of my career has been spent in the let's make it obvious and revisitable. I actually remember very clearly early on in my time at thoughtbot, I was working on something and was working on it with Joe Ferris, who is the CTO of thoughtbot and a very clever individual, and I mean that in the truly positive sense of the term, one of the most capable engineers I've ever worked with. He was describing an anecdote, but it was basically he'd put up a pull request. And someone replied, "Oh, that's clever." And Joe's reaction was, "Oh, crap." Just taking that as not an insult but as someone saying, oh, that's clever in a positive way, and Joe hearing that in the negative form of I went too far here, or this is not obvious in its initial interpretation. That really stuck in my head from there, just his reaction to it immediately of that being not a good thing. And I was like, that is interesting. And all the more so over time, I've come to believe that clever is probably something to avoid in code. STEPH: Yeah, agreed. I'm at the point that if I do see someone who's done something that I do think is clever in a positive way, I will still abstain from using that word clever because I do want to make sure they don't think that I'm saying in a bad way that this is clever, that it's not readable, and it's not friendly. So I totally avoid that word when I'm complimenting someone's code just to make sure there's no confusion. CHRIS: It's one of those words that got away from us that we lost the definition of, and then we came back, yeah. Mid-roll Ad Hi, friends, and now a quick break to hear from today's sponsor, Scout APM. Scout APM is an application performance monitoring tool that's designed to help developers find and fix performance issues quickly. With an intuitive user interface, Scout will tie bottlenecks to source code, so you can quickly pinpoint and resolve performance abnormalities like N+1 queries, slow database queries, and memory bloat. Scout also recently implemented external service monitoring, adding even more granularity when it comes to HTTP requests and API calls. So give Scout a try today with a free 14-day trial and experience first-hand why developers worldwide call Scout their best friend. And as an added bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. To learn more, visit scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. CHRIS: Let's see. In other news, you had mentioned this earlier, and then I had mentioned my side of it but errors in alerting and all of those sorts of things. They're an interesting question. We had a small situation over the weekend that turned out to be kind of real, kind of not real. But I happened to be away on vacation. I did have my computer with me because, at this point, we're early enough. And I'm like, I'm going to take my computer everywhere and just be ready in case it's necessary. And in this case, I did get a ping. I looked into it and what was unfortunate is it wasn't immediately obvious if something was broken or not. And to a certain degree, that's always going to be kind of true. There's so much noise, so many requests hitting a web application. And how do you tell the good ones from the bad ones? And ideally, I could threshold around certain volumes of traffic, but even that's going to have spikes, and ebbs and flows and things like that. So it was very hard initially to understand is something actually broken? And then all the more so to understand what was broken. Thankfully, it was tractable. It was solvable. And we've done, I think, some good work especially considering how early on we are and how we've instrumented things in Sentry, in particular, our usage of Sentry and also somewhat in the logs. But again, I think I've talked about this before, but I'm feeling this tension around there's data. There's data just kind of like, what happened? And right now, we've got logs. That's one of the places that goes to Sentry if it gets escalated up to that level. And we sort of have a weird Venn diagram between logs and Sentry. And then we also have analytics as another thing and then eventually data science, and what do we want to try and learn? And all of these kinds of want different facets of it's not the same data set. But I wonder, is there a superset of data that then we could filter and slice and cut up, do all those sorts of things? I think this is the dream of Honeycomb and platforms like that, but I'm not even certain if that's true. And so I'm in that awkward middle space is how I would describe it. But in that particular case, I was able to resolve it. I did take away as an action it's probably time to start thinking about PagerDuty anomaly detection, that sort of thing. When does alerting happen? When do engineers actually get calls when not just during the normal nine-to-five of the workday? So I'll be investigating that in the coming weeks and see where we get to. But it's sort of the first thing that really pushed us in that direction. The other thing I'll say is we have the idea of the point dev, which I've talked about on a couple of episodes. But the idea is for each week, one individual on the engineering team is in charge of the noise, for lack of a better term. They're looking at the error stream in Sentry. They're looking at any ad hoc requests that are coming from our admin team, et cetera, et cetera. And that's been really great. But one thing that I've noticed is that dealing with the errors is particularly tricky and what we did in this particular case was just to pair on that. As an individual, it is really hard to sometimes to reproduce, sometimes to just understand these are the things you didn't expect in your code, and therefore they are, by definition, harder to understand, harder to think about. And then sometimes you get to an understanding. You're like, ah, what do we do about that? Do we care? Do we not care? Is this just noise? Is this something we should solve? Is it something we should solve soon? Or is this something we can solve whenever we get to it in the backlog? And making that sort of determination is all the harder. And so I'm increasingly of the mind that there should be some amount of time that is pairing on that error backlog to bring two heads together. I hadn't been thinking of it this way, but I've now come around to thinking this is a really great place for pairing because it's so hard for one individual to deal with that complexity to make the hard value judgments. And to do that, if each individual does that in a vacuum, then we have n different value systems at play that are hopefully very similar. But if we start to pair up, then there's osmosis between those groupings. And ideally, we sort of coalesce towards a shared value structure around, like, what can we ignore? What should we snooze for a week? What should we put in the backlog? What should we prioritize and fix immediately? Because I think those are really hard things to otherwise...that's really hard to document, I would say. I would love to write up a page in the Wiki that says, "This is how you treat errors," except each error is a unique snowflake, and you just have to follow your values. STEPH: I have been on teams where we've written up documentation that helps you triage an error because you're right; you can't write documentation around a specific error. But that I always found really helpful where it was like, here's all the links that you can look at, here are some recommendations. When we were working on an application that was falling over more often, there were some specific outlines around if you see this problem, then this is typically how you can solve it. And then we had to fix that at a larger scale, but it was a nice band-aid to get us through at that point. I like the idea of pairing, especially as you mentioned; it's tricky. It's funny when you mentioned capturing those errors and putting them into the backlog because I like that idea that then you can prioritize and bring those into the sprint. It just made me feel a bit hesitant. If we don't work on it now, we're never going to work on it. But then that feels unfair to say because it really comes down to the team. If you have a team that's going to be able to look at those errors and say, "Yes, we're going to bring them in and prioritize them," then that feels really good to then be able to say, "This is an error. Let's capture it. Let's provide some content around it. But it doesn't need to be addressed at this moment. It's still pretty low in terms of risk for users or at least low in impact for users." So yeah, I guess it just depends as long as the team feels good about being able to prioritize errors, which I feel confident that your team would be able to do. And if you can't, then y'all could reassess that plan. CHRIS: That's why we definitely have that. We're revisiting the errors. They're part of the same backlog as everything else. So they're coming up in relative priority and getting worked on and getting resolved. But we're also shifting our thinking just a little bit to say, "We should take a little bit more time in the moment to try and resolve some of these where we can." I have the dream of there are just zero bugs ever. But that's hard, especially in different platforms. And we're seeing a lot of mobile traffic and from different older Android versions and so weird JavaScript edge cases and things like that. Like, why does your runtime not have object? That feels like a thing every JavaScript runtime should have. But that's a joke. Every JavaScript runtime, I'm pretty sure, does have object but that sort of thing. It's like, whoa, this is weird and specific to this one device. Cool, those are fun. So yeah, giving a little bit more time to do those. And again, so we definitely do have the document that describes here are the places to look and how to think about this category of error and this category of error. But at the end of the day, you get one that's just like, there's not a ton of detail in the error. It's hard to reproduce. It might be device-specific, et cetera. And so what do you do in that moment? And that's where we're trying to...I think pairing is a great way to share that thinking around the team. So overall, it's been great, though. I think everyone who has been involved has been like, "This was better than when I did it on my own," so cool. STEPH: Awesome. That sounds great. CHRIS: Yeah, I think so. This is one of those ever-evolving facets of how we work as a team and how we build the platform. So I will certainly report more in future episodes, but for now, happy with that. And yeah, what else is up in your world? STEPH: Yeah. So we've been looking specifically into tooling around how we're going to spin up more machines to process more RSpec tests. So specifically, we have around 80,000 RSpec tests that we are processing, and we have one machine that is parallelizing those and takes around just for that portion of the build because then there are other tests and things that get run that brings it up to about a total of 30 minutes. But for the RSpec portion, I think it's probably around 20-ish minutes to process those 80,000 tests. So we split that across four different containers, and then we run those tests. And so we'd really like to spin up more machines to then process because we've reached the point that we have given as much power to that one machine as possible. So now we're looking to add more machines. And one of those solutions that we're looking at is using Buildkite, which is built with the idea that you can add these build steps so then you can more easily say, "All right, once we get to this particular build step, hey Buildkite, we'd like to run n number of machines to process all these tests." And that seems really nice. And it is something that we are interested in. It is actually what Shopify uses. They use Buildkite ci-queue, which is built for mini-tests, which is what they use, and Redis to then run all of their tests. But we are using TeamCity, so we're not using Buildkite. And we would like to see if we can grow with our current CI infrastructure versus having to move to a new one. There's a lot of just risk involved in moving to a new one. And so we've been studying hard if TeamCity will let us do this. And so far, the answer has been no. But just recently, we found somewhere in the docs that it looks like there is a chance that with TeamCity, we can inform TeamCity that, hey, even though we have just this one build step, instead of only giving us one agent or one provisioned machine to then run these tests, instead that we actually want to spin up a couple of machines to then process these and then aggregate the results back to this one step. So we're looking into that. But I wanted to throw this out there in case anybody else is also using TeamCity and has already invested in this particular approach. I would love to hear about it because we are currently figuring out the capabilities and if this is something that we can stay with our current infrastructure or if we're really going to have to look for a new solution. CHRIS: Well, I'm hopeful that someone out there can give you some input. I definitely get the idea that you're stuck, and stuck is maybe too strong of a word. But if TeamCity is not ideal, the idea of moving off it does feel exceedingly heavy and the riskiness that you talked about. That's, I think, a critical word here because I think it's easy to think of CI as like it's a very important thing. But that's absolutely critical as part of your deploy pipeline, I assume. This is speaking generically about CI, and so it is, in fact, a critical piece of the infrastructure. If you've got a bug on production and suddenly CI is down, what do you do? I guess you can test locally and decide you're going to push past it, but then you have to circumvent it. And so I understand the intentional way that you're thinking about that and the risk associated. I do wonder, though, if TeamCity has felt like not the right platform for a while and if there are considerations. Is there the possibility of both trying to improve the world that you have now, so it's not the big move off of it but then also in parallel start to work on an alternative implementation? This is perhaps not entirely fair, but it feels like a Rails application is this repository of code. And typically, CI is configured via a file. And that's like, if you've got your teamcity.yaml or whatever it happens to be, could there also be a buildkite.yaml that is not on the critical path for deploying or anything like that? But it is a way to, frankly, somewhat inefficiently test on two different platforms but start to see if you can get the code moving on a different platform and be able to gradually build out and make that transition possible without it being one big swap over sort of thing, which eventually it would need to be. But just wondering, is that happening in parallel? Is that a possibility? STEPH: I think the short answer is, I'm sure there is. There's a way to look at the existing system and then find ways that we can tweak it. But I also know that the team has already invested a lot into working with the current system and making it as efficient as possible. So I don't know if there's any true big impact but intermediary steps that we can take. We are definitely in that proof of concept world. So we're not going to move anything over for the rest of the team until we can really prove that something is working for a small subset and then start to expand from there. But currently, our idea is to dig further in TeamCity, which I think also includes just a call to their team and say, "Hey, we'd love to talk to one of your engineers and see if the thing that we're trying to do if it's possible. Let us know if it's not and if we need to look elsewhere," which is intriguing to me because having a lot of tests isn't new. There are tons of companies that have lots of tests, and they want their CI test suite to be fast. So a company that then has built software that helps Team execute these steps that then the ability to say, "Hey, I want more machines to process. I want to give you more money and to give us more machines, and we can process more things." I feel like that should be a thing. And I'm getting at the edges of my knowledge. This is why we're exploring all of this. But it has been surprising to me to realize that that doesn't seem as easy of a thing as I would have expected it to be. There are also some other concerns around here where the client that we're working with if we're going to work with third-party vendors, then we have to get special approval to work with them. It's not just a hey, we can just go try it out. It's a lengthy contract process that we'd have to go through. So there are also some constraints that we have to keep in mind where we can't just work with anyone. We need to be careful to make sure that they're certified in a particular way. So yes, I like your idea. I will definitely keep it in mind. But I don't know if there are any true intermediary steps yet other than the building out a proof of concept and then finding small ways that we could move over. Then I think that would be ideal for sure. And then hopefully, if there's anybody that's listening that has experience with TeamCity or Buildkite, that's the other tool that we're looking at using, let me know. I would love to chat about it and find out your experience. On that note, shall we wrap up? CHRIS: Let's wrap up. The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
DITA w modelu "docs as code"? Kto to widział? Czy to się da zrobić i czy to w ogóle ma sens? Po snuciu teorii na ten temat, przyszedł czas na konkretne działania. Rozmawiamy o tym co do tej pory udało nam się zrobić, żeby w naszej organizacji wdrożyć "DITA as code". Mówimy o narzędziach, przykładowym procesie robienia zmian w dokumentacji, napotkanych trudnościach i kolejnych krokach. Jeśli "DITA z gita" jest bliska Waszemu sercu to zapraszamy do odsłuchu. Dźwięki wykorzystane w audycji pochodzą z kolekcji "107 Free Retro Game Sounds" dostępnej na stronie https://dominik-braun.net, udostępnianej na podstawie licencji Creative Commons license CC BY 4.0. Informacje dodatkowe: "#16 DITA z Gita", Tech Writer koduje: https://techwriterkoduje.pl/blog/2020/04/22/dita-z-gita "#8 DITA OT - static site generator dla wtajemniczonych", Tech Writer koduje: https://techwriterkoduje.pl/blog/2019/09/28/dita-ot Standard DITA (Darwin Information Typing Architecture): https://en.wikipedia.org/wiki/Darwin_Information_Typing_Architecture Component Content Management System (CCMS): https://en.m.wikipedia.org/wiki/Component_content_management_system Git: https://git-scm.com/ "Docs as code", Write the Docs: https://www.writethedocs.org/guide/docs-as-code/ Bitbucket: https://bitbucket.org/ Git submodules: https://www.atlassian.com/git/tutorials/git-submodule Bitbucket pull requests: https://www.atlassian.com/git/tutorials/making-a-pull-request Oxygen XML: https://www.oxygenxml.com/#bidx-xml-author "Krytyczna podatność w bibliotece Apache Log4j": https://cert.pl/posts/2021/12/krytyczna-podatnosc-w-bibliotece-apache-log4j/ Sourcetree: https://www.sourcetreeapp.com/ DITA Open Toolkit (DITA OT): https://www.dita-ot.org/ Docker: https://www.docker.com/ Amazon Simple Storage Service (S3): https://aws.amazon.com/s3/ TeamCity: https://www.jetbrains.com/teamcity Schematron: https://www.schematron.com/ "Content Reuse": https://paligo.net/docs/en/content-reuse.html Git hooks: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks "Readability – what is it and how do I improve it?", Paweł Kowaluk (soap! 2018): https://www.youtube.com/watch?v=LzrHrIOHhz8
Chris updates us on his new window manager of choice, Moom, and tells us what's good with it. He's also giving yet another task manager a go: OmniFocus. (Sorry Things.) Steph talks about defining test classes in RSpec and readdresses flaky tests to improve CI build time. Chris is worried about productivity. He's still not coding as much as he'd like to be. Steph lends an ear, and together, they discuss potential ways Chris could gain back a little bit of coding time at work. This episode is brought to you by ScoutAPM (https://scoutapm.com/bikeshed). Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Moom (https://apps.apple.com/us/app/moom/id419330170?mt=12) OmniFocus (https://apps.apple.com/us/app/omnifocus-3/id1346190318) Is It Worth the Time? (https://xkcd.com/1205/) Knapsack Pro (https://knapsackpro.com/) Shopify Monolith (https://shopify.engineering/shopify-monolith) Sacrificial Test Classes (https://blog.bitwrangler.com/2016/11/10/sacrificial-test-classes.html) rspecq (https://github.com/skroutz/rspecq) Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: STEPH: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Steph Viccari. CHRIS: And I'm Chris Toomey. STEPH: And together, we're here to share a bit of what we've learned along the way. So hey, Chris, what's new in your world? CHRIS: What's new in my world? Well, hey, Steph. Oh, I have an update on a thing that I think I talked about a while back or at least asked on Twitter. But I've been looking for a window manager for forever. And in that way that I sort of overcorrected a while back, I think where I'm no longer allowed to do anything related to productivity or dev tools. I was just forbidden because it was a time sink. I'm slowly trying to correct back and be like, you know what? I regularly think about how it would be nice to have a better window manager. So previously, I had used Divvy, D-I-V-V-Y, which is fine. It did an okay job, but it just didn't have quite the level of control that I wanted, or maybe I didn't investigate it enough. But it felt like it was lacking. So I did a little bit of research. A bunch of people recommended different things. There was Spectacle; there was Rectangle. There was a whole bunch of other things that I'm forgetting now because I have settled on Moom, M-O-O-M. Those are fun words. STEPH: I feel like you keep bringing interesting words [laughs] because last time, it was Things where you're tracking all the things. And now we have Moom to track the space. All right. CHRIS: If this is my legacy as a podcaster, then I feel like I will have done well just, you know, weird sounds mostly that's what he's going for. But yes, I've been using Moom now for…[laughs] God, it's just ridiculous to say, but here we are. STEPH: [laughs] CHRIS: I've been using it. I've been enjoying it. In particular, the thing that I liked about it...a bunch of the other ones that I looked at were like, oh, we've got all these different configurations. And you can move things any which way, and you can have any number of hotkeys. And I was like, wait, wait, wait, say more right now. You want to take over my global namespace of hotkeys and just clutter it with 19 different things? You know that that is a limited space that I'm working with here. And so Moom, somewhat uniquely, at least in the ones that I experienced, was what I would describe as a modal window manager. So much like Vim is modal where you start out in normal mode, and you're moving around and you kind of bounce and search and all of that, and then you enter insert mode. And in insert mode, keys do different things. And then in command mode...it's got all these different modes. And so there are lots of different namespaces for hotkeys. It's one of the things that makes Vim so powerful. Moom is similar in that there's one global activation hotkey. And then, within that, I can have a whole namespace of hotkeys. So like M will put something in the middle of my screen now. F will put something full-screen. And I don't need to remember weird multikey combinations for that. There's just the one to get started, and then I've configured it such that the tab will bounce to a secondary display and sort of rotate through them. M and F and Q and P I've got it physically laid out on the keyboard. So it looks like my screen. Q being on the left side will push something to the left side, P to the right side. And I'm very happy with that. I don't need a lot out of this tool. I don't need very complex management or scripting or any of that, which are very nice features that exist in the other ones. But that combination, the one hotkey to rule them all, and then the sub hotkeys within it, and the ability to mostly move between the screens and then put stuff where I want it is great. I'm very happy. STEPH: I think I've figured it out. So Moom, I think it's a combination of move and zoom, and that's how they got Moom. CHRIS: You're probably right. STEPH: That does sound really nice. I'm a Spectacle fan. And I have enjoyed it and just stuck with it because I haven't felt a need to change from it. And it's really nice where I use my arrow keys for which direction I want to go. So that has been easy for me to recall. But that sounds really nice, all the things that you're describing with Moom. CHRIS: Does spectacle have the like, is it some Command Option Control and then left or right or up or down? Or is it you type something, and then you type left, right, up, down? STEPH: I have to actually touch my keyboard to answer that question because I have the muscle memory, which is an interesting thing that my muscles knows it, but my brain has to really think about it. So I think it's like the Option Command, and then yeah, then use the arrow keys. CHRIS: Gotcha. That's roughly what I had when I was using Divvy previously, but I found just enough of a limitation there. And so Moom has been great as another tool. But I think Spectacle has a lot more features in terms of scripting and other fancier stuff that you can do, which is both super intriguing and, again, sort of the thing that I'm not allowed to do. [laughs] So I went with, like, this tool seems fine and has the one feature that I really want. That said, you brought up Things, which is the to-do list app that I've been looking at. I've been using it for a week now. It's great. I'm enjoying having a more structured way to say, like, here's what I'm doing today. Here's what I'm doing tomorrow. It's been wonderful. But I'm already looking at OmniFocus as a better version. STEPH: [laughs] CHRIS: Because I think there's some stuff that I don't love, and yes, I can hear my own voice in the back of my head that's like, always chasing that next thing. But I haven't actually made the effort to switch over or even tried. I've used OmniFocus in the past. But anyway, I'll let you know if I do make additional moves there. STEPH: Yeah, I'm enjoying this journey. Keep me up to date on it. I've heard of OmniFocus, but I know nothing about it. But I feel like I've heard good things. So I like this journey you're going on where you just keep switching and trying new things. That's fun for me [laughs], and there's chasing productivity. So I'm into it; I'm here for it. CHRIS: If I just invest enough hours to save a handful of minutes down the road, then I will have...oh no, wait, that's not how this goes. There's, of course, an xkcd about this which we can include in the show notes. But I'm trying to be very intentional with it. I waited for many years before I allowed myself to reinvestigate the world of to-do lists. And I'm hopefully going to keep it to just a couple of weeks of nonsense and then back to a few years of stable. That's the dream. But yeah, that's some of the smaller things that are up in my world. I have another topic that I want to chat about. But I'd love to hear what's new in your world? STEPH: Yeah, I have some interesting bits that I can talk about with the project that I'm working on. But more concretely, I have something that's been on my mind that I don't think that I've talked about here on the show, but I think would be fun to talk about because I just happened to run into it this week while working on some code. And it's the idea of defining test classes in RSpec so as you are testing part of your code, but then you want to create just like a fake class, something that you can use as a substitute for real application code. And so it's a really nice way that then you can have this replica behavior, but then maybe it's just one particular method or some behavior that you need to use in the class but then doesn't actually go to the real code. That's wonderful. That's great. One thing that I've learned is that with RSpec is when you are introducing a test class, so let's say if you have your RSpec describe and then either a string or it's the name of a class, and then you have a block so do, and then within that block is where you write your test. If you create a temporary class, say, like I have my class test class, and then I have some behavior, that gets defined in the global namespace. It's not scoped to that particular RSpec example. And the reason for that it's not specific to RSpec. RSpec is not the one that's doing this; it's actually Ruby behavior. So for Ruby, when you're defining within a block like that, if you're defining a constant, if you're defining another class inside of a block, it's going to use the outer namespace as its namespace. So if you had a top-level class that you were defining, but if you define a class as a block, and then inside of that block you define a constant, that constant is then defined in the object namespace instead of within that particular class that you have written. And so that's why RSpec has this behavior. Because someone brought up a really great question about this on RSpec::Core asking about it, and they're like, yeah, that's actually how Ruby works. And so we're not going to change RSpec's behavior since that is how Ruby has decided to handle this. And the part where this becomes important is when you define a test class within an RSpec example. While it may be unlikely that someone is going to use that exact same name for their test class that they're going to create in their RSpec example, if they were to use that same name, then you're going to have a collision between the two. One of them's going to win, and you're probably going to end up with some really weird test failures because it's going to get confusing as to which class is being used, and they may not match up with each other. So one way around this, and this is going to be one of the rare times that I suggest this, but let. Let is scoped to an RSpec example. And so you could define a class inside of a let, and then that will scope it to the example. There are probably some other approaches as well, but that's the one that I'm most familiar with to ensure that when you define that class or constant, it's not getting defined in the global namespace and ensuring that none of the other tests have access to it. CHRIS: Well, this is certainly interesting. I'm pretty sure I've been operating under the opposite assumption for the entirety of my career. This is good to know. I feel like I probably have had tests that failed because of this. And then I learned this truth, and then I subsequently forgot it. I don't know if you know this, but if you define a method within just a helper method that you extract in RSpec, are those also on the global namespace? I don't define classes in RSpec blocks that often. It's pretty rare. Like if I have a controller concern sort of thing that I want to test, I might say random controller and inject the thing there or some other abstracted piece. That is the only case I can think of where I have a fake model or a fake controller or something like that for test purposes. But it doesn't come up that often. I do extract a heck ton of local helper methods. And I'm wondering now, are those all in the shared global namespace? STEPH: I'm pretty sure they're not. And I'm getting on the edges of my knowledge here, but I think it has to do with the fact of when you're defining a constant. So if you're defining a class versus an actual constant, that will get into the global namespace because it's using the outer scoping. But in my experience, I'm pretty sure that's not true for the method just because I remember one time I did some funky stuff with RSpec. And I remember seeing that I couldn't access those methods from another example. CHRIS: I like the honesty. And you're like, to be clear, I was doing something weird, but I learned that day. Okay, that's good because at least that part maps to my understanding. So methods may be safe, but classes get shared. Very interesting. STEPH: And it's something that I rarely think about or had worried about just because if I'm defining a fake test class, I often will put it somewhere that's intended to be more global. So I'll stuff it somewhere in like spec support. So then other people can see, hey, I've already mimicked this behavior. So if you need to use the same thing, just go ahead and use this. It's not often that I am adding that class directly to the RSpec example group. So I think I've been fortunate where I haven't actually run into that conflict for that reason. But this came up while giving an RSpec course. And while we were just in a very small, tiny codebase and replicating some examples, someone in the class was like, "Hey, by the way, do you know that that's in the global namespace?" And I was like, "No, friend. Tell me more." So thanks to that person, they're the ones that actually enlightened me about how it's going into that namespace and how it can actually pollute your testing namespace. There's a really good article that's written by Ken Mayer. And we'll be sure to include a link in the show notes that talks about it and also provides the let example as a way to work around this. And also links to the GitHub discussion on RSpec::Core, where they talk about this behavior and why things are the way that they are. Circling back to some of the more general project-y things that I alluded to earlier, I've shared a bit about the project that I'm working on. But just to recap it, it is focused on helping a very large team that has a large number of tests, around 85,000. And they are looking to address flaky tests that they have and overall really improve their CI build time. So right now, it takes about 30 minutes for the build to take place. But they also have flaky tests, and then that slows things down. And so, the re-verify rate has been painful for them. There's been some really great work that has improved that, particularly there is a, I think we've talked about this before, but where they're re-verifying certain flaky tests, which isn't great because they're still flaky tests, but at least they're not preventing people from moving forward and shipping code. But some of the bigger stuff that is just on my mind is when you have a very large team and a very large application, by large team, I'm talking about 100 developers, and they are all contributing to this codebase. And there are around 85,000 tests, and that has grown substantially in the last 12 months. And so, if you think about the trajectory of the addition of those tests, it is just going to continue to grow. So there's a concern there of even if we address flaky tests and we improve things, there's an architecture concern of how do we really reduce the CI build time? And so there's that aspect, and then there's also the aspect of then well, how do we still work to improve the tests and the codebase as well as we go across all of these disparate teams? And right now, there is a bit of a culture where engineers don't feel empowered where they can necessarily address all of the flaky tests or things that they run into. And so there is a bit of a mindset of I'm stuck on this, or this test failed, or it's flaky, or I don't understand it. So I'm just going mute it, or I'm going to hand it off to someone else to work on it. So there are three big areas that are on my mind. The first one is architecture. You can throw architecture at it. There's also the code quality that's a concern. And then how do you improve the code quality in a way that you're improving it fast enough that then you've got 100 other developers that are also contributing to it at the same time? And then individual IC empowerment where then people feel like, hey, I ran into a slow test or a flaky test, and I feel like I can triage this, and I can make changes. For the architecture piece, we're still in the infancy stages of how to approach this and the strategy that we're using. But one of the ideas that has come up is how do we reduce tentpoles? And the tentpole is like when you're running your test and, let's say that it's parallelized, all of the various tests. But there is one process that takes like 20 minutes, and then the other process is completed in 5 minutes as a drastic example. And overall, you could have reduced your time if you had managed to split that 120-minute process across all the other workers who are then available for that work. So there are some tentpoles that are taking place. And that could be one first step in reducing the CI build time. There are also discussions around how to scale horizontally. Right now, we don't think that's something we can do with the service that we're using to run the test. But it's something that maybe we need to manually look into is then how do we build a queue of all these tests and not where we just split test by a file, which is typically how the Parallelize gem does it. But you could actually split up tests within a file. So if you had a particularly large file, that doesn't necessarily matter. But then building a queue of all these tests so then as each test finishes, a worker can just grab that next test. And then also you can easily scale up and scale down workers. As I'm saying that, that feels big, that's a lot to invest in. But that as an idea is how can we essentially then scale the architecture? So even as we continue to invest in the tests, in the system, and they continue to grow, our architecture can keep up with it. CHRIS: That last bit there is super interesting to me. It's something that I've looked into and haven't pursued yet. We're currently running on CircleCI with our test suite. And I don't even know that we pushed on parallelization because we're early enough on that. And we turned off bcrypt recently, which super-duper helps with the speed up. But overall, the test suite time is fine, is where I would put it. It had crept up, though, to a place where it was starting to be painful, is how I would describe it. And I think it's very easy for that to just continue growing and suddenly, it's 20 and 25 minutes. And then, depending on your merge strategy and all of that, it can be all the more complicated, and this gets in the way of deploys. And so, I think it is a super important thing to keep an eye on. I know Charity Majors pushes really hard for 15 minutes from merge to deploy to production. And so if your CI suite takes 25 minutes, then already you're stuck. As an aside, I just once more want to say out into the ether, CircleCI or any other CI platform, if you would allow me to say yes, we've already tested this Git hash, this Git SHA, or the working tree, ideally, because that's also deterministic, I would love that feature. I would love to not have to rebuild the same code when it gets merged into main, just saying once more out into the world. Also, GitHub, if you want to put me on the merge queue beta, I would love that if anybody out there is listening. [laughs] STEPH: I like how this has become a special requests hotline for all the things [laughs] that you're hoping to get a part of or features you'd like to see added. CHRIS: Hello, internet. I have some requests. STEPH: [laughs] CHRIS: I would love to see those things, but in the world where those don't exist. The particular thing that you're talking sort of a test queue, is something that I've seen. So Knapsack is a...what's the word? It's a tool; it's a service. It's a combination of things. But it does that essentially where it starts up a local build agent. And then it basically says like, all right, give me all of the tests that you need to run, and then I will feed them back to each of the individual agents that there's one agent running per parallelized process. And so say you've got five of them. The first one says, "Hey, give me a test," and runs it. And the second one says, "Give me a test," and et cetera. And so, the queue manager on the other side is in charge of that orchestration. And it means that they basically all finish in identical time, with one being an outlier, whichever one happens to be the longest. But it's only going to be however long your longest test is is basically that outlier versus what you're describing of like, well, if we split it by file, we can end up with more naive things where there's a bunch of feature specs on one of them, and it skews by two minutes. We obviously don't want that. So Knapsack, in particular, is a tool that I've looked at, but generally, I'm very interested in that as a solution to how do we maximally take advantage of parallelization there? STEPH: Interesting. I have not heard of Knapsack. There is one that sounds similar. It's called RSpec Queue. And it does some really interesting work where it will split the individual test, so it won't do it by file. It will also look at historical data to then try to be intelligent about how it's going to split it and find the longer running test. And I believe it uses Redis to then keep track of the test set up in run and things that still need to be run. That is a gem that the team is looking into using as well. I don't know how that works if that can integrate with the current platform as we're using TeamCity to run tests. I don't know if that's something that can integrate with TeamCity, if it's a replacement. I don't have all of the knowledge about RSpec Queue yet. But it seems to do a number of the things that we're interested in. So even if we can't use the gem, then maybe it's something that we can still imitate. CHRIS: The other thing that I'm surprised we haven't said yet is this is one of the places where people would often reach for microservices. I feel like we have to have the microservice conversation at this moment. Microservices can actually be a great solution to organizational problems. As a team scales, it does become really hard to manage a large group of developers. And so microservices introduces a very fixed boundary that then draws nice lines that you can have around things. And so, the individual build time for a portion of your application can be much more manageable by virtue of that. But it has this huge cost of technical complexity and overhead and et cetera, et cetera, all of the reasons that we may not want to go that route. And so interestingly, I was just looking at Shopify's Deconstructing the Monolith blog post, which I think at this point, they've skewed a little bit more into the microservices. Shopify is huge, one of the largest Rails apps out there. And so looking at them and being like, oh, what are they doing? It's an interesting sort of plot a course and to see how long they waited before they even started thinking about the much deeper things and even exploring microservices. But in this blog post, they talk about a different approach where they stuck with sort of a monolith. But then they started to introduce Rails engines and clear encapsulation within the large codebase such that then you can actually start to say, well, we don't need to run all the tests every time because if we're making a change within this section of the application, then we just need to run those tests. I've also heard of organizations having some logic that can determine based on the code change; we know the associated test files that we should run. I'm scared of that is how I would describe it. I want to trust my test suite. I want to be able to deploy on a Friday and say if tests are green, it's going out to production. That's great. And I worry about that sort of thing. That's hard to get right. That feels like caching, right? And that's one of those things that we historically get wrong a lot. But nonetheless, that is an approach that large organizations I've heard having good success with. So some way to determine what's the affected code and what tests do we need to rerun and et cetera. And that can really drastically reduce down the scope of each CI build. But those are some larger things that I have not had to reach for on any of the applications I've worked with. I've taken different approaches, different ways to reduce the time or otherwise Parallelizer et cetera. But it's interesting for when you get to a certain scale. STEPH: Yeah, it's funny that you bring up that idea because that came up in conversation with some of the other developers as well, was the idea of, like, what if we could just not run all the tests? You changed one file, and you don't need to run everything. And I immediately was like, that sounds very cool and super hard to be able to get right. And a lot of this code is extremely coupled, which then moves to the code quality area. So I suspect a lot of the test times could be improved by creating smaller objects because right now, a lot of the tests will load the entire world because they have to. They have to test everything. And so that is creating a ton of data, and then taking a long time to run versus if we were able to split out that code into smaller objects and test in unit tests, then that would also help speed up. But that's also hard to do. Where do you look first? We do have some great data, thanks to RSpec. RSpec is letting us know how long each test file takes to run, and then we are capturing that data. So I can go look at which files and say, oh, this file takes 10 minutes to run. Let's look at that file first versus some of the other ones that are performing better. But that is a battle that will take a long time to win. And it's something that takes consistency and then also encouraging others to join that battle. So while it's very important, it doesn't address the concern of tests growing rapidly and then being able to support that. Something that you said in a previous episode also was on my mind in talking about building processes in a way that encouraged people that they can make small, quick changes. And I think that's really important. So if we can build out the architecture to help scale this so then the tests were running in say 15 minutes, then if someone saw a test and they wanted to make a small refactor, they saw a factory.create, and they're like, oh, that could be a FactoryBot.build_stubbed instead and issue that into a pull request or change request and get that merged. I don't know if people feel as comfortable doing that right now because it takes them 30 minutes or longer to run the test. But that idea of how do we get a structure in place where people can make tiny, little improvements and do that as a whole, as a team, to then work on the code quality concerns? CHRIS: That last little bit is so interesting where you're saying, like, oh, we have a FactoryBot.create, FactoryBot.Build, but it has the overhead of having to go through the 30-minute test suite. But coming back to the thing we were talking about before, what if we didn't have to run all the tests? Although I find it very hard to tell, given a code change in actual production code, what tests do I need to run? When I'm just changing a test, I'm pretty sure I know which test I need to run in order to determine if that test still runs correctly. So that feels is there an optimization that can happen there? Which is I've only made test changes; therefore only run the changed tests. And then that's an encouragement to say, like; this is a part of our codebase that we are trying to improve on. Let's optimize the iteration speed there. You'd have to figure out how to write that. And so it's probably much like my productivity adventures, maybe not a good investment. Although given that this is such an organizational concern, maybe that is the thing that's worth spending an afternoon on and seeing if it could happen. Because if you can speed that process up, get more [inaudible 23:46] and more iteration in fixing the tests, that feels like it could be a win. STEPH: I think that's a really good idea. I think we could certainly tell that if a file's changed, that it's only a test file that has changed. And then I've heard very good things from the other developers that TeamCity has a wonderful API to work with. And so there's a way that we could then tell TeamCity to say, hey,...or it may not even be a TeamCity command. It may just be somewhere in the universe we have to say, "Hey, RSpec, only run this test," or "TeamCity, we're only going to feed you this one RSpec test to run, so user agent but only run this particular test." So I really like that idea. I think that's really intriguing. And I'll bring it up with the team because that would be a huge win, especially as Joël and I are really focused more on tests. That would just improve our lives. So selfishly, I'm excited about that idea because we are touching less of the application code and more focused on improving the test at this point. CHRIS: I mean, if right now you're getting, say, 5 or 10 pull requests through a day which frankly feels like a high bar on this, if suddenly that's 10 to 20, that's material right there. STEPH: Yeah, I don't know how large of an impact it would have for the rest of the team because I don't know how often they're only making changes to a test file, but it still feels like a nice optimization to have. Cool. Well, thanks. I appreciate that idea. CHRIS: My pleasure. Mid-roll Ad And now a quick break to hear from today's sponsor, Scout APM. Scout APM is leading-edge application performance monitoring that's designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve those performance abnormalities like N+1 queries, slow database queries, memory bloat, and much more. Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform. See for yourself why developers call Scout their best friend and try our error monitoring and APM free for 14 days; no credit card needed. And as an added-on bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. CHRIS: What else is going on in my world? I continue to not code a ton which is interesting and probably makes sense for right now. But to share a small anecdote from this week, we had retro, and I ended up attending retro ever so slightly late. I was doing a hiring interview, which is super exciting. Again, for anyone that's out there, we are hiring at Sagewell Financial. And I would love to chat with you if that sounds interesting. But so I was having a wonderful hiring conversation that ran a little bit long. So I was a little bit late to retro, and I arrived, say like eight minutes in, and someone was expressing a concern. And the concern was, I very sincerely know this to be true, but they were saying in the most positive way. But they were like, "It'd be great if Chris could code more," and not in the judgmental like, Chris, why are you not getting as much done? Not in that way at all, very much in the it would be great if Chris had more time, if there wasn't as much pulling my attention in different directions. But then it kind of went into this interesting direction. So we then go back through and address the concerns and talk as a group about how we resolve them. But this one was like, my name was in the concern, again, in a very positive way, in a very supportive way. And we had a wonderful conversation, and there were really great ideas that were passed around. But man, did I feel weird having my name in a retro item. [laughs] STEPH: So one thing I've learned is that you do a really good job when you are giving presentations and being in the spotlight. But I don't think you actually love it. You love sharing content and things that you have learned. But I could see how being a focal point, especially if there's a concern or something that could have a negative connotation, that would feel squeamish. It would make me feel squeamish. CHRIS: I hadn't thought about it in that way. But as you say it, also, this conversation is a meta version of that. Like, let's talk about me talking about me. I don't want to be the center of attention. But I love technology or process. I love talking about the work. That's great. And so I'm happy to do that. I'm happy to stand in front of a room and talk about it. But yeah, when it's about me, that's weird. And so now I'm going to move...well, no, I'm not going to move on [laughs] because this is the topic right now. But so there's a bunch of things that we have been trying to introduce. And I think this is a useful part of the conversation more broadly and less about me. So one of the things that I think I mentioned in a previous episode was the introduction of point-dev, which is each week, we rotate through a person. And that person is in charge of triaging the errors, making sure that nothing is stuck in Sidekiq, responding to any support requests, et cetera, et cetera. But they're meant to be the frontline such that everyone else can be heads down and really focus on the work. And what was interesting of the three developers that are working on the project, I am point-dev this week. So I was like, yes, that's awesome this week because I'm the person on the frontline. That has not helped me, but in the future, it will. And then one of the other developers mentioned that they feel like it's really useful but also feel like it's been noisy. And we realized the previous week was their week on point-dev. But the other developer was like, "Yeah, it's been great. I haven't had to think about anything." And so they have been off of that rotation for two weeks now. They'll be taking it over next week. But it is doing exactly its job of providing that attention coverage so that they can keep their focus on the code, and that's really wonderful. So I'll be honest, when we started talking about it, there was a tiny voice in my head that was like, is this a failure mode? Should we be dealing with the noise rather than having a process to address it in the moment? Should we be dealing with the root cause rather than the symptoms? And I still think that's a good point of view. But we found so much value from this. And as I've mentioned it, many people are like, oh yeah, we have that. It's great. I've heard enough positive things. So I've backed away from that. But there was a voice in my head that was like, are we failing right now? But yeah, so point-dev has been really wonderful. And next week, I will have to...well, frankly, the next two weeks, I'm off of point-dev appointments, so I'm very excited about that. I've been doing some of the product management or sort of the tech side of the product management and helping to triage cards and make sure that there's very clear work lined up for the engineering team when they're ready to do that. I'm trying to back away from that just a little bit. And one of the things that we did there was introduced an inbox column in our Trello board. You know how I love a good inbox. You know how I love to get to inbox zero. But that is a good way for me, for anyone now in the organization, which I don't want everyone to have to learn our processes, but just saying, "This is the place that you put requests, and we will deal with them. I assure you of that." It has been great because that means I don't need to be quite as responsive in Slack. I can just gently redirect people, "Hey, if you don't mind, please put this in Slack in the inbox column, and that'll be great." That thing, though, that gentle pushback in Slack is one of the things that I've struggled with. And this was one of the more personal aspects of the conversation that happened in retro was me being, like, if we're being honest, I tried to do that. But it's not my favorite thing to do in the world. Whenever someone asks me something, I want to be helpful. I don't want to seem rude or brisk or like I'm too busy for you, et cetera, et cetera. So I will often respond to the question or do the thing that they're asking and then say, "In the future, if you could go to this other place." And ideally, I'm slowly moving forward and being like, "No, no, no, please go to the other place. We've talked about this a few times." But it is an interesting example of one of the specific aspects of my personality coming through in this. But that introduction of an inbox has been great. Love me a good inbox, as I said. And then, more generally, we just tried to talk through what are the things that I'm doing? Do I need to own all of those uniquely? And some of them the answer we decided was yes but some of them we decided no. And we started to sort of distribute the work there or some of the meetings or different aspects of it. And so overall, it was a really great conversation but also very weird for me. STEPH: Yeah, because then you wonder, am I not doing the right thing? Am I not spending my time the right way? But then hopefully, that meeting helped reinforce that yes, you are spending your time the right way and that you're doing a lot of productive things. There are just too many productive things for you to do, and so you have to prioritize those aggressively. I like all the things that you just highlighted. There's one in particular, the last one that you mentioned about finding things that you can hand off to others. And I love that for a couple of reasons. It came up in a recent conversation that I was having with some other thoughtbot developers around when someone's on a project, typically someone just falls into being the point person. They just happen to be the person that the client talks to and ask questions and goes through the most. And that's something that is okay. But we want to make sure that that's not a bad thing, that everybody is treated equally, that everybody is given equal opportunities and room to grow. And so, in my mind, whenever someone is that point person, or you have fallen into that role, it is your job to then pull other people up. So if you have been given the responsibility of running a particular meeting each week, then go ahead and do it once or twice, so you can demo it and show it to someone else as to how you do this. But then tag somebody else and say, "Hey, I'm going to let you or ask you to run this next time." So then that person can experience it. They can demo their style, and then it continues on to have more people. So I really like that you are highlighting it's not just beneficial for you to then distribute those tasks, but it's empowering for everybody else on the team as well. I'm curious, so what was the final outcome? It sounds like there are some really good things in place, and you're transitioning, handing some things off. But I can't imagine that things have gotten...all of your priorities are still there. So do you think you'll actually code more, or what's the outcome for next week? CHRIS: Short term, maybe probably not, if we're being honest, but trending in that direction. So one of the things that's going on right now is hiring. That is just an activity that takes a lot of time. And I care a lot about doing that well, both for the organization and then for individuals on the other side. I want to be respectful of their time and communicate in reasonable timelines and not leave people without an answer or follow up or those sorts of things. It probably makes sense for that to sit with me as the starting contact. And then from there, folks that are continuing on in our hiring process they're going to talk to many other members of the team, and that won't just be me. But there are a lot of first conversations that I'm having. And so right now, my schedule has a bunch of that, which is fine and good. And that will hopefully, at some point, we'll hire some great people. And then we'll be on the other side of that. And that piece of the work that I have right now goes away. Some of the other outcomes that we named there were a couple of action items. And so I think those will help, but they're sort of we got to work towards that. One is transitioning a meeting, but it's a biweekly meeting. And I'm not going to just not attend the next one. So it'll be me and one of the other developers attending to transition ownership of that meeting moving forward. And then from there, so like, two weeks from now, I will not have that consideration on my calendar. And that's like one 30-minute block that I get back or, depending on how you think about it, one block that that 30-minute broke up. I do want to touch back just on something that you're saying there. I think you're being very kind to me in saying like, no, but you've got so many things, and so it's hard to do that. I think that's true, but that's kind of the work overall, and my version of that is one thing. But everyone sort of has, as a team, we have a version of like, how are we being most productive? Are we making sure we're doing the most important things? And so it was interesting in the moment, but I think it was a very good conversation. And I want to make sure that both we as a team and then me as an individual, wherever that happens to be the case, are open to these sort of constructive things. Like, frankly, to do the work to figure out how to get work off my plate that hasn't felt like the most important thing. It felt like close to the most important thing, but then there were all the other things that I had to do. So I wasn't doing the work to figure out how to not do the work. It is a complicated sentence that I just said. But this was a case where retro, I think, very usefully highlighted that this was a good thing for us collectively to put effort into such that we can be more productive moving forward. It happened to be slightly more focused on me rather than the entirety of the team. But broadly, that kind of thinking is why I'm a huge fan of retro. I think it's a great place to take a step back think about how we're doing the work rather than just being in the work day-to-day. STEPH: So if I'm internalizing what you said correctly, let me know if not, but it sounds like you're in one of those places, and I've witnessed this with other people and myself where someone is overwhelmed. They have a lot to do, and they're very focused in that grind and in that moment of doing all the things that they have to do. And it's very hard to then say, "I'm in the weeds right now. And then I also have to figure out how to get out of the weeds." And that's a very different skill and mental space to be able to do that. Because often, when you're just in that mode, all you can focus on is a bit on survival at that time. And then it may take other people to notice to say, "Hey, you're in the weeds. We need to figure out a way to help you not live there and to find ways to distribute some of the work." Does that sound like a fair assessment? Because I think I say all that because I've just seen people in that position. And then they think back, like, oh, I should have offloaded stuff earlier. And it's like, yeah, true, totally. And it often takes a retro or someone else coming to you and saying, "Hey, I've noticed...I looked at your calendar today; how can I help?" [laughs] CHRIS: I think that's probably the right calibration. And mostly, my emphasis was just I want to make sure that broadly, any team that I'm on has the space for this sort of conversation. And that thing that you're saying exactly that phrasing of like, "Hey, I saw your calendar. How are you doing? How's that going, though? Are you feeling okay? [laughs] You can't sleep and whatnot." That can be a really useful thing to have and to have organizational norms about what are our expectations of how many meetings someone should have in a week. And where do we start to think about different things? You did use the phrase overwhelmed. I want to say that I'm like 101% whelmed. So I'm just ever so slightly overwhelmed, but it is like I'm in the weeds. I need to figure out how to clear some of the weeds so that then I can get out of it. And it was a great conversation that came from that. STEPH: That's awesome. I'm glad you got a good team that, frankly, felt comfortable bringing it up, and then that you could lean on them for ways to talk about how you could code some more and talk about priorities and where you want to focus your time. CHRIS: It will be an interesting thing. As the team grows, I don't expect this to get easier. We talked about this a number of weeks back. And I think for a while; hopefully, we clear a little bit of dust here, and then I get back to being a little bit more on the code, and that's going to happen for a while. But as I think about the longer sort of the future of the company, this is something I'm going to have to revisit a handful of times. And it's a really interesting question that I'm still struggling with internally. And where do I want to be versus what will be needed and whatnot? So it'll be interesting to see how it evolves. But for now, I think I can gain back a little bit of coding time, a little bit of maker time versus manager time, as Paul Graham's essay goes. And yeah, I think that'll be good. STEPH: Yeah, I like how you're already looking forward to the fact that it will probably fluctuate because, yeah, right now, you are sort of paying a tax. You are building up to then where you can have more people on the team. And then that may give you back some of your time where then you can code because you can outsource some of the work to them. But then, as the team grows, so are other responsibilities. And traditionally, being in a CTO role and most CTOs I know will code here and there because they want to, and they enjoy it, but it is not their full-time job. So I think you're really wise to have already noticed that and start thinking about how that's going to trend in the future. And it sounds like you might need to figure out how to throw some architecture at it. So then you can scale horizontally, and then you can just have more time to do all the things. Yeah, that's right. [laughs] CHRIS: You're suggesting microservices, right? That's how my job becomes easy? STEPH: Yeah. Well, I'm thinking more like RSpec Queue, but we'll have RSpec Chris or some version of that. CHRIS: Chris Queue. STEPH: Chris Queue. [laughs] CHRIS: And then I just paralyze my human, and then it'll be great. STEPH: Yeah, that's always worked out well in the movies. Whenever somebody clones themselves, that goes super well. CHRIS: Multiplicity is a fantastic piece of cinema, and I stand by that. STEPH: I haven't seen it, but I feel like it doesn't end well for the main character. CHRIS: I feel like every time I mention a movie, you haven't seen it. I feel like we need to do a movie marathon at some point just to catch up so that we've got shared analogies. But yeah, it's a fun movie. It's fine. It turns out fine in the end. But there are some humorous adventures that happen in the middle. Cloning maybe [laughs] isn't the most direct option to solve productivity problems. STEPH: [laughs] Yeah, I think I've got Labyrinth, Hackers, and Multiplicity now on the watch list. And I appreciate the fact that you know that I'm not likely to watch them, although out of the three, Hackers will probably happen. CHRIS: All right, what if I were to get a bunch of Pop-Tarts, non-frosted? STEPH: Ooh. CHRIS: Does that change -- STEPH: Wait, are you going to send them to me? Because if you just have them, that's no good. [laughter] CHRIS: Eat Pop-Tarts on a video call and be like, "Look at this movie. It's great." [laughter] STEPH: All right, bribery definitely works for me. [laughs] CHRIS: Okay, so got it, noted. And based on the nature of the conversation that we have devolved into here, I think we've probably reached a good point. What do you think? Should we wrap up? STEPH: Let's wrap up. CHRIS: The show notes for this episode can be found at bikeshed.fm. STEPH: This show is produced and edited by Mandy Moore. CHRIS: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review on iTunes, as it really helps other folks find the show. STEPH: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed or reach me on Twitter @SViccari. CHRIS: And I'm @christoomey. STEPH: Or you can reach us at hosts@bikeshed.fm via email. CHRIS: Thanks so much for listening to The Bike Shed, and we'll see you next week. All: Byeeeeeeeeeee!!!!! Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Steph started a new project and shares details about the new tools she's using, including working on a remote dev environment. Chris shares a journey with Lograge and Rails flash messages as he strives to capture user-facing errors. They also discuss "silencing" flaky tests, using Graphviz to visualize data dependencies, and porting Devise views to use Inertia and Svelte. It's also interesting how different their paths have been this year! This episode is brought to you by ScoutAPM (https://scoutapm.com/bikeshed). Give Scout a try for free today and Scout will donate $5 to the open source project of your choice when you deploy. Joel Quenneville (https://twitter.com/joelquen) GitHub - roidrage/lograge: An attempt to tame Rails' default policy to log everything (https://github.com/roidrage/lograge) Graphviz (https://graphviz.org/) Become a Sponsor (https://thoughtbot.com/sponsorship) of The Bike Shed! Transcript: CHRIS: Tech talk nonsense and songs, that's what people come to The Bike Shed for, variations on the Jurassic Park theme song, you know, normal stuff. Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Chris Toomey. STEPH: And I'm Steph Viccari. CHRIS: And together, we're here to share a bit of what we've learned along the way. So, Steph, what's new in your world? STEPH: Hey, Chris. Let's see. So I've started a new project. So frankly, there's a ton of new stuff in my world. And I've been on the project for about a week and a half now. I started over the holiday, and it's been going really well. Still in that whole early stage with getting to know the application, the codebase, the processes, the team, all the dynamics. It's a large company. So I'm working with a small group of individuals, but there are about over 100 developers that work at this company. And they do have a lot of documentation, which has been very helpful. But there's a lot to learn in terms of setup and processes, specifically. So they have provided a laptop that I'm using to access their codebase. So I'm using their laptop. And then, I am also using a dev machine, a remote dev machine, that they have set up for me. So I need to be on their VPN and SSH into that dev machine. So that's novel as well. CHRIS: Ooh, I'm very intrigued by that bit, not that they gave you a laptop bit but the dev machine. This is in the cloud sort of thing? What is this? I'm very intrigued. STEPH: I don't know if I have concrete answers for you. But yes, for me to be able to access their codebase, I have to go into the dev machine. And then that's where then I can do my normal development work. CHRIS: So is this like an EC2 instance or something like that that you're SSH-ing into, and then you can run processes on it? Or is it closer to the GitHub dev containers thing that they just released? Or are you running with your local Vim? Is it a remote Vim? Are you using Vim? Is it VS Code? I have so many questions. STEPH: [laughs] I think it's more like the first version, although I don't know the backbone of it. I don't know specifically if it's an EC2 instance or exactly how it's being hosted and how I have access to it. But I did have to set everything up on it. So they started the dev machine up for me. Their DevOps team started an environment where then I could access, and then I did need to cultivate it to my own habits. So I had to install several things. I had to install Brew and Vim and also the tmux and all those configurations that I'd really like to have. They do have a really nice Confluence document that walks you through how to set up a connection between VS Code and the remote environment. So then that way, you can really just hang out in VS Code all day. And initially, I was like, okay, I could do this. And immediately, I was like, no, I love Vim. I'm going back to it even if I have to spend the 20, 30 minutes setting it up. I'm so comfortable with Vim and tmux that I stuck to my roots, and I didn't branch out into VS Code. But I think VS Code is one of the more popular tools that they're using. So that way, it feels more local versus having to work in a remote machine. I think I answered some of your questions. I don't think I answered all of them. CHRIS: Yes. I think you did answer all the questions. But just for clarification, the Vim and tmux and whatnot setup is that you're running SSH, and then on the remote machine, you are using Vim and tmux? Or is it a local Vim that is doing…I think Vim has some remote editing capabilities but not anywhere near what VS Code can do. STEPH: It's the first setup. So I am SSH-ed in. And then I have Vim and tmux running on that remote machine. CHRIS: Gotcha. Novel. STEPH: Yeah, it's a thing. It's working. So that's good. And it feels cozy. I feel like I'm at home. I feel like I can be productive. So that's great as well. Some of the other tools that I'm also new to, so they use Zeus, which is used to then speed up the booting of your application. And you can also use it for speeding up test runs. So very similar to Spring, which I think we've had some discussions about Spring and who loves it and who doesn't. [laughs] CHRIS: I don't know. I'm not...[chuckles] I feel like I remember Zeus. But Zeus is like three iterations ago of this preloader thing. I'm intrigued by that. I thought Spring had fully supplanted it in the Rails ecosystem but maybe not. STEPH: So this company has been around for a very long time. So there are a number of tools that I think they're using because that was the tool to use the day when they got started. And then it just hasn't been a need to move on to one of the newer tools to use Spring. So at least that's my current explanation for why we're using Zeus. And also, Zeus works most of the time. I'm frankly still getting comfortable with it. [laughs] I still have gripes about Spring too. CHRIS: 60% of the time, they work most of the time. STEPH: [laughs] So, Zeus is another new tool that I'm adding to my tool belt during this engagement. Another new tool that I'm using is Gerrit. And so they use Gerrit…it is used for managing their Git repositories. It is used for code reviews. And being as accustomed and familiar with GitHub as I am, that one has been a little tricky to then navigate and change the whole UI that I'm used to when it comes to pushing up code, reviewing code, asking for feedback on changes. And at one point, I was reviewing a change request for someone else. And there's a button on there where I was adding comments, but they were in draft mode. And I'm trying to figure out how to get them out of draft mode so that they're actually submitted, and the other person could see it. And I saw a submit button. I was like, cool. So I hit the submit button. And then it said something in red text about ready to be merged into main. [laughs] I was like, oh, no, I mean, maybe, but that's not what I meant to do. So I had to reach out to that person and be like, "Hey, I'm new to Gerrit. I don't know what I did. I hit a button. I hope everything's fine. Here's my review. Best of luck. [laughs] I think everything is fine. Nothing dramatic came out of it. But I had my own little dramatic moment. CHRIS: Wow, that is a bunch of new stuff. It's interesting. On the one hand, I totally understand projects get started, and there's a certain set of tools that are current at that point, and so then you're using them. And then, over time, it takes a very active effort to try and keep up with the new current, that new-new as we call it. But the trade-off there is really interesting because, at any given time, it never feels like the right investment to pursue the new thing to just upgrade for upgrading sake. But then the counterpoint is the cost to someone like you coming onto the project. And it's like, it's a bunch of new stuff. It's kind of old stuff. It's new for me, but it is old, and less documented, and less familiar. And it's also certainly less compatible with other things that are going on, almost certainly. And so, how to stay on top of those updates is always the thing that's really intriguing to me. I say as someone who started a project recently, and I have not thought about upgrading anything at this point. And we have bundler-audit I want to say is the one thing that we have in there. So if there's a CVE for a gem, then security-wise, we will be upgrading those. But otherwise, I haven't thought about upgrading our Ruby version or anything. And I think we're on 2.6 or something like that, which is a couple back at this point. And so it's something that's in the back of my mind. I feel like I should have a formal answer to this. Like, company-wide, how do we think about the process of upgrading? And Dependabot and things like that answers some of it, but that doesn't tell me when to upgrade Ruby, I don't think. It could. That would be annoying. I don't want that. But it's one of those many things that depends and is subtle. And you have to decide where you put the trade-offs and whatnot. So just an interesting thing. And to observe you now going into this project building and being like, there's a bunch of new stuff. STEPH: I think it really takes passion or pain. Those are the two things that then prompt us to upgrade. Either it's pain, and you need to change it to get rid of that, or it's passion. So you're really excited about the next version of Ruby or the next version of Rails. And I think that's fine. I think that's fine that those are often our drivers. But yeah, that is interesting. I hadn't really thought about that in terms of there's often no real strict process around when we upgrade except those are then the natural human catalyst. CHRIS: I think you're right that those are the catalysts. But I think quite often those cannot be sufficient to push us to do the work. And so what do you do in the absence of that? It's not really painful. And I'm not really passionate about it. But I probably should do it is the 80% of the time middle space that we live in. And so yeah, I don't have an answer to it. I'm more observing the question. But like so many other things, I feel like often we just exist in that awkward middle and got to find a way through, so how like life. STEPH: I was having a conversation with someone earlier a bit about these life cycles that we live in. Specifically, we were talking about consulting and how changing from project to project is so daunting. Because you go from I'm accustomed to this project, I'm accustomed to the team. And then all of a sudden you jump into this new project and with all these new things it can be really interesting. But then there's also this feeling of like, wait, I used to be smart, and I knew everything that was going on. And the team knew me, and I knew all the team processes, and I felt good. And now I'm in this totally new space, and I have to relearn, and I have to reprove myself and relearn all the company politics. And there's always that initial jumping from a sure space over to a very new space that always makes me then question and be like, yeah, I can do this, right? I can do this. And then I have to keep letting that voice build until about two weeks in. And I'm like, oh okay, I'm back in a good spot. I said two weeks; it's probably more like four. But there's still that grace period of a new project where you're leveling up on all the things and learning the new team. And as daunting as it is; apparently, it's what I like. Apparently, I like that roller coaster ride that comes from jumping from one project to the next. So on that note of a bit of novel insight into myself, what's new in your world? CHRIS: What is new in my world? Let's see. I think I've got two updates, two anecdotes to share. One, I lost the battle, one I won the battle. So we'll go with the lost battle first because that seems fun. So we have Lograge on this application, which Lograge, for anyone that's not familiar, is a library that helps with producing more structured and more complete log lines from a Rails application. You can tell it to do JSON log lines, which is useful for many of the tools that will receive your logs. And then with it, you can say grab me the controller name and the params but sanitized and this and that. And so, you aggregate a bunch more data than would traditionally be in the logs. In general, I've just found it to be a much better foundation. I find the logs to be more readable, and more informative, more useful, all those lovely things. But slowly, I've been looking at what's the other stuff that I want to have in here? What else would be nice to know? So one example is we use Inertia on this project. And Inertia has a particular way in which errors get mapped back to the front end. And it's an interesting little trick that involves the session, but that's sort of an aside. Basically, this is something that the user will see that I would love to know about. So how many users are hitting their head against the wall? Because typically, whenever these errors happen, that means this is a flash message or something like that we're going to show to the user. So we were able to add that into our log lines. Now we can see those. We can aggregate on them. We can do counts. We can do alerting and monitoring, all those kinds of fun things. So cool. That was great. That worked well. I then specifically…I mentioned the flash a second ago, but that's actually not…the Inertia messages will not show up in the flash. They end up in forms inline on certain inputs or whatnot. But we do also use the flash message pretty regularly as a way to communicate to the user success or failure or what have you. And I really wanted to get those into the logs. And I tried very hard, and I failed. I gave up. I threw in the towel. I raised the white flag. So the nature of the flash, which is something that knew in the back of my mind but I had never really experienced as pointedly as this, is the flash is a magic value within the Rails ecosystem that can be written to and then once read clears itself. That's the nature of how the flash is supposed to work. And it persists across requests. So it's doing some fun stuff there, which I assume is tunneling through the session or maybe putting it into a cookie. I'm not actually sure. But there's some way that you post to an endpoint, and then you get redirected to the show page. And on the show page, we actually display that flash value. But the flash is set on the controller endpoint that is handling the POST request. So this value spans across two request-response life cycles, which is interesting. And so the manner in which that works is Rails is managing that on our behalf. We write to it on the one side. And then, when we do the subsequent requests, if there's a value in the flash, we show it to the user, which is why occasionally you'll see those weird things where that flash message shouldn't show up. But it's like a sticky value that was left in the system that didn't get cleared via one thing or another. But I really wanted to put those into the logs. Like, what are we saying to the user is the thing I want to know. This is that question of like, what's my system doing at runtime? I understand what it's doing. I can read the code and understand what should happen. But what actually happened? Are users seeing this flash message way more than they should? That's a question I want to be able to answer. And I have lost the battle. I cannot find a way to read the flash value, put it into my loglines, but then also have it persist through. The first attempt I did, I was able to get it into my loglines, but then it didn't show to the user, which is a bad outcome. Because now I've read the value, Rails clears it, cool, that's fine. There is a flash.keep method. And that I thought would do the thing I wanted, which is like, oh, I want to read this value. I want to tap this value, I want to observe it, I want to peek at it. And I thought this keep method would do the thing that I wanted. It did not. It just caused the flash to be persistent. So now, anywhere I went had the same flash message for forever, which was not the behavior that I was looking for. I then tried, like, all right, just for exploration purposes, what if I reach inside and read the instance variables of the flash objects? Also did not work. Everything I tried did not work. And it had these fun failure modes that just made me very sad. Thankfully, we had feature specs that told me about this failure mode because I would not have known about it otherwise. This was not obvious to me on first implementation. But yeah, I lost, and I feel sad. And then I did the thing that we do, which is I searched Google, and there's nothing. I cannot find…This is one of those cases where like, I can't be the first person who wants to know what's in the flash. I can't be breaking new ground here. And yet I couldn't find anything on the internet. So that's where I'm at. STEPH: That's interesting. Yeah, I'm trying to think…I think I'm one of those people. I don't think I've ever tried to peek into the flash and see what's there ahead of time. And it makes me wonder if it's partially…so we can't peek into the flash. You've exhausted several examples or tries there. When you're setting the value of the flash, it makes me wonder if there's an order of operations that you have to pursue. So before you set the flash, you know what messages that you're going to share. So you send that off to the logs, but then also share that to the flash. So instead of writing the message directly to the flash and then having to check the flash, if you just stored that value elsewhere and shared it to the logs first. Is that a reasonable approach? CHRIS: It definitely could work. But that was in the space of this is getting weird enough. I thought about things like that, but I didn't want to do anything weird. And part of the benefit that I get from using Lograge is rather than having multiple lines for each request…so a request came in and rendered this partial and did this thing. It gets constructed such that there's a single logline, which is one big JSON object that contains all of the data about that request. And I really liked that structure because then everything's correlated like, oh, did we 404, or did we 302? And what was the message that we said to the user? And what were the params? It's all there in one line. I found that to be really useful. So I wanted to do that. I could just separately log it. But then I'm also worried of there is a statefulness there. Because again, the flash is written on one side and read on the…it's like a Hail Mary to ourselves between requests. Look at me with a sports reference. And so, I didn't want to try anything out of the ordinary. I really just wanted to find a way to just like; I just want to read this value but not like Heisenberg uncertainty principle observing changes in the system. I found myself in that space, and I was like, can't there be a way that I can just flash.peek? And I just want to take a quick look. I don't want to mess with anything. You do your normal thing, flash. Just let me know. And I do not have an answer for it yet. And for now, this is one of those nice to have, not an absolute requirement. So I wasn't yet in the position of okay, fine, let's do some out-of-the-box ideas here. So I'm still in the in the box phase, I would say, but who knows? Maybe down the road, I'll be like; I would really love to know what the flash message was for that request because this user is seeing stuff that we do not understand. And that information would tell us the answer. So we're not there yet. But I was surprised by how thoroughly I was defeated by Rails and the flash message on this adventure. STEPH: I am equally surprised. I wouldn't have thought that particular achievement would have or is proving to be that hard or, frankly, not doable. So yeah, I'm intrigued to see if anybody has thoughts on it or if you do find a different solution because Lograge is one that I haven't used. But I would be surprised if other people haven't had a similar request of like; I want to be able to store what's in the flash message. Because like you said, that seems super helpful. CHRIS: Well, certainly, if I do figure anything out, then I will share that with the world. But yes, part of this is putting it out there into the universe. And if the universe happens to send me back an answer, I will happily accept that. But yeah, again, I had two stories, and that was the one where I lost. I'm going to send it back over to you because I'm interested in anything else that's up in your world. And later, I'll tell the story of a victory. Mid-roll Ad And now a quick break to hear from today's sponsor, Scout APM. Scout APM is leading-edge application performance monitoring that's designed to help Rails developers quickly find and fix performance issues without having to deal with the headache or overhead of enterprise platform feature bloat. With a developer-centric UI and tracing logic that ties bottlenecks to source code, you can quickly pinpoint and resolve those performance abnormalities like N+1 queries, slow database queries, memory bloat, and much more. Scout's real-time alerting and weekly digest emails let you rest easy knowing Scout's on watch and resolving performance issues before your customers ever see them. Scout has also launched its new error monitoring feature add-on for Python applications. Now you can connect your error reporting and application monitoring data on one platform. See for yourself why developers call Scout their best friend and try our error monitoring and APM free for 14 days; no credit card needed. And as an added-on bonus for Bike Shed listeners, Scout will donate $5 to the open-source project of your choice when you deploy. Learn more at scoutapm.com/bikeshed. That's scoutapm.com/bikeshed. STEPH: I have a victory that I can share as well, and I'm excited to hear about yours. So to share a bit more context about the project that I'm on, we are focused very heavily on improving their test suite, not only the time that it takes to run the test suite but predominantly addressing a lot of the flaky tests that they have. Because that is a huge pain point for the team and often leads to the team having to rerun tests. And so, there are a couple of areas that we're very excited to make some contributions. The first part is that we are just looking at those flaky tests to figure out what is going on and how can we address these? And one of the nice things, one of the tools that they're using TeamCity is the tooling that they're using to run their automated test suite. And TeamCity will let you mute tests, so then that way, if you do encounter a flaky test, you can mute it. So then, at least it's not impacting other people. I say this with some asterisks that go along with it because, for people who can't see, Chris is making a very interesting face. I think you have thoughts on this. And the other thing that they will show is a flip rate for the flaky tests, which is really nice, too, because then you can see which tests are flaky the most. So then that helps us prioritize which ones we want to look into. All right, I'm going to pause so you can respond to that comment I made about muting tests. CHRIS: I'm intrigued. I talked in a recent episode about adding RSpec::Retry. So the idea of flakiness being a thing that exists and trying to decide how much engineering effort to apply to fixing it. But the idea of muting it and especially muting it in the UI, not in the test suite or not having that be something that's committed, there's something about that that caught my attention, and thus apparently, my eyebrows raised. You saw that. [laughs] But I don't actually know how I feel about it. This is such a complicated, murky area that I wish I had a stronger set of beliefs around. It was interesting when we talked about the RSpec::Retry thing. I think you rightly pushed back on me, and you were like, that's interesting, maybe don't do that. And I was like, that's a fair point. [laughs] And so now hearing you're in the quagmire of flaky tests, and yeah, it's an interesting space. STEPH: Well, I think my hard belief is that muting tests is a thing that we shouldn't do. It's going to lead to more problems, and you're not really addressing the issue that you have. It is a temporary solution to a much bigger problem that you have. And so it is a tool that you can use to then buy you some more time. And so that is the space that this team is in where they have used this particular tool to buy them more time and to be able to keep shipping changes while realizing that they do still need to address these underlying issues. So it is a tricky space to be in where essentially, you've gotten to the point that you do have these muted tests. It is a way to help you keep going forward, but you are going to have to come back to it at some point. And so that's the space that I'm in right now joining the team is that we have been brought in to help some of their engineers specifically address this issue while ideally letting the rest of the team continue to focus on shipping changes while we address the test. Although I really think there's going to be two angles that we've talked about in how we're going to help this particular codebase. One of them is that we are going to address a flaky test. But the other one is empowering people that they feel like they have the time and the knowledge that they can address a flaky test and also not contribute more flaky tests to the codebase. But I appreciate that you called me on that a bit because we've had those conversations around when we should actually address something versus muted, all the interesting trade-offs that come along with that conversation. So this particular flaky test that we addressed earlier this week is specific to hard coding primary IDs. The short version is that it's bad, don't do it. The longer version is that they were having a test that was failing intermittently because it would pass the first two runs, but then it would start to fail for all future runs. And the reason it would pass for the first two runs is because when they were setting the ID for a record that the test setup is creating, they were looking for existing records and saying, "Hey, what's your latest ID?" And then I'm going to guess the next ID. I'm going to add one to that to figure out what the next ID should be. Some additional context, when the tests boot up, there's some data that's being created before the test run. So then that's why they're checking to see, okay, what records already exist? And then let's add one to that. The reason that fails sometimes is because then once the tests have run, the Postgres IDs aren't being reset, so they're using a truncate approach. So then, when the test runs once or twice, that works. But then, at some point, there's a collision between those IDs where they tried to guess the next ID, but then Postgres is also on that same ID, and it ends up failing. There are also some callbacks. There's some trickery afoot. It took a little while [chuckles] to work through these tests to understand why they're failing. But the short version is that we thought we had to restructure the data in a way that no longer required us to guess what the next primary key should be for a record. We could actually use Factory Bot to generate that record, and then ask Postgres, okay, what ID did you assign? And we're going to pass that in. And that part was really challenging when you're in a new codebase, and you are learning the domain knowledge and exactly how data should be structured. So that was one challenge of it. The other part was that a lot of the data relies on each other. So then figuring out the right hierarchy in which we could create the data. So we didn't have a circular reference at some point. It took some time. And Joël Quenneville, who's on the project with me, used a tool that I found very helpful. It's called Dataviz. He went through and documented the let statements, the data that's being created, and then it generated a nice tree structure that shows you okay; these are your dependencies. This is the test setup that you're using. And then from there, just by changing a few lines in that particular file that used to generate that Dataviz tree, he would move it around. And we could simulate what we were already mentally trying to construct in our head. So as programmers, we're already thinking, okay, I know this record needs that data. And that data needs that data before I can build this. But this actually turned it into a concrete visualization where we could see it. And I was really struggling. And he was like, "Hey, I got it into a visual form that we can look at. And there's a circular reference. That's why this keeps happening and why we're not making progress." So then, using that, we were able to then reformat some of the dependencies, look at the graph, see that we didn't have that circular reference anymore. And then we could implement that in code. And it really helped me to be able to walk through that visual aspect because then I could say, okay, this is all the stuff that I'm trying to mentally hold on to, but instead, I can just look at this and know it's going to work. I don't have a circular reference. It also helped concretely show why the previous efforts were failing and why we kept running into some issues. So I'm really interested now in Dataviz because I found it very helpful in this particular case. And I'm very intrigued to see if I can apply this to more tests that I'm trying to fix and to see if I can start out with here's the current structure. Here's where I'm trying to go. And then essentially build that graph first before I start changing the code around. I would love to have that optimization. And I feel like it would speed up the process. CHRIS: It was funny as you started to say that I had observed some tweets going out into the world recently. And I was like, this is Joël. This is definitely Joël talking about these things. As an aside, for anyone who doesn't follow Joël Quenneville on Twitter, @joelquen, I would highly recommend it. We can include a link to Joël's Twitter in the show notes. Joël is one of the clearest thinkers and communicators about programming that I have ever worked with. And in particular, what you're describing of the data visualization is something that I think he does incredibly well. Often he'll make blog posts, but they'll include just simple little visualizations, little images, or diagrams, or flowcharts that just so concretely encapsulate an idea and express it so much better than text ever could. And so, in so many ways, I look to Joël's writing, both on Twitter, in the blog, in many places. And I just appreciate so much what he puts out there and the manner in which he does it. So I was by no means surprised when you said, "Oh, and I'm working with Joël on this project." I was like, yes, I bet you are. That sounds true, and in particular, some of the conversations about flaky tests and determinism and all of that. So yeah, the visualization stuff is also particularly interesting in taking a system that it's very hard to hold all of this in our heads. But that visualization, the tree and/or graph thing at play, having that in a picture and being like, oh, look, there's a cycle now. There we go. Can't have those. That's not okay. That's a really interesting solution that's just very cool to hear about and presumably led to a good outcome where you were able to break that cycle. And now you're happy and deterministic in your tests. STEPH: Yeah, it's one of those approaches where I wonder if it was helpful afterwards and how can I make it helpful beforehand? Because it felt like a confirmation of the pain in the process that we had been through. And I'm eager to see if now I can apply it ahead of time and save myself some of that pain. That's where I get really excited. But yes, it was a successful outcome. And we have fixed that particular flaky test. But I'm very excited to hear about your victory from the week. CHRIS: It's a shared victory. It was a team victory, just to be clear. But we are working in a system that is using Inertia. Inertia.js is a project that I've talked about a number of times on the show. I'm a huge fan of it. It is the core architecture of how we're building our application. But as a very brief revisiting of what it is, on the server-side, we have Rails, and Rails is acting in a pretty traditional way. We do not have an API. And on the front end, we have Svelte, which is a JavaScript view layer framework. Inertia sits between them and binds the traditional Rails MVC architecture and the Svelte front end. So again, there's no API in the traditional sense of this is a REST endpoint, and we hit it, and we get some data, and then the front end holds on to that in a store. None of that is going on. Inertia does a wonderful job of marrying these two concepts and allowing us to use familiar programming techniques on the server-side but then also have a more future-friendly front end. Animations and transitions and things like that are now totally possible while not throwing away the entirety of our programming model that we've had in Rails server-side applications. That's all well and good. Almost all of the UI in our application is rendered via Inertia and Svelte. That's great. We love it. The one caveat is Devise. So we have Devise on this project, and Devise comes with a lot of views built-in. And we have both an admin and a user model. So we have sign in and sign up, and confirm registration, and forgot password and all of these different views and flows and things that Devise just gives you out of the box. And being an early-stage startup, it was not a good time to revisit any of that or to try and build it from scratch or any of that. We just wanted to build on the good known trusted foundation that Devise gives us. But the trade-off there is that now all of our Devise logic lives in this uncanny valley. It's the only stuff that is in ERB views. Our styling, thankfully, we're using Tailwind, and so we are able to have some consistency between the styling. But recently, we redesigned the flash messages on the client-side in our Svelte pages. But on the server-side, they are a little on the Devise-side because Devise is the only pages that are being rendered truly server-side. They look a little different. And this is a pain that we felt, that inconsistency or that mismatch between the Devise views. And then the rest of the application is a pain that we felt but one that we consistently were like, I don't think it's worth the effort to try and change this. Finally, this week, we've been doing a lot of work on our user onboarding funnel. So the initial signup flow going through it's a progressive form screen where you go in between different pages. And a majority of it is implemented in the Inertia and Svelte side of things. And it's very nice and very fun to work with. But the signup form, the user signup form, is in Devise, and it's a traditional Rails server-rendered post, and then all the normal stuff happens. We finally decided to bite the bullet this week and see how painful it would be to port that over to Inertia and Svelte. And spoiler, it was awesome. It was very straightforward, and coming out of it, immediately, the page was largely the same. The server-side code was largely the same. But now we had things like when you submit this form, if there's a validation error, we don't clear out your passwords because we're staying on that page on the client-side. We're taking advantage of the way Inertia's error flow works. That's a subtlety of how Inertia works. That's probably more detail than we want to get into here, but it's an awesome thing that works and is great. And so immediately, this page just got better. We got inline errors for each of the fields. We were able to very easily add a library called Mailcheck, which I've talked about on an episode a while back. But this is a thing where if you have a typo in your email address, we can say, "Hey, you have a typo in your email address. And if you click this link where we suggest the alternative, we'll just replace it inline." That would have been really awkward to wire up in our Devise view. It would have been some jQuery-esque script tag at the bottom of the view page that doesn't stop…We don't have jQuery actually at this point. We wouldn't have jQuery. And we could certainly, but it would only be for that view. And it would be weird and different in a fundamentally different programming model. It was trivial to do in the Inertia and Svelte world once we had made that port over. This was always my hope. This was the dream that I had in mind. And it speaks to the architecture of Inertia. And Inertia is a really great abstraction that is very minimally leaky. I won't say it has zero leaks because no abstraction does. But this was my hope is I think the server-side should mostly stay the same. And I think the client-side, we just take an ERB template, turn it into a Svelte template, and we're good to go. And that has largely been the case. But suddenly, this page is so much more. There are subtle animations as things come in. And there are just lots of nice features that were trivial to add now and that fit with the rest of the programming model that we have throughout it. So that was awesome. STEPH: That is awesome. I love these styles of updates where there's like, oh, I had a loss this week. But I also had this really great win because that feels just so representative of a typical week. So I love this back and forth. CHRIS: It's also that sequence is how the week went. So the loss happened earlier in the week, and then the win happened later in the week, which is how I would prefer it because now I'm going into the weekend with a win. Like, cool, I'll take it. Had it gone in the other direction, I would have been like, oh man, Rails beat me. But I guess it's the weekend now. I'll forget about it for a little while. STEPH: Yeah, that definitely helps to end on a positive note. CHRIS: But yeah, I don't think too much more to say about that beyond it was both really nice to get the added functionality to get the better, more user-friendly behavior in this view that naturally falls out of this programming model. But also to have that reinforcement of my belief in Inertia as a good architecture. Not only did we get some really nice stuff out of doing this port, but it was also pretty straightforward because Inertia sits so comfortably between the pieces. And that's a story that I really like. I want more of that in my programming world, where to change this thing requires changing everything in our app. Oh no, this is sad. No, this was a great example of we were able to very minimally change things and get a much better experience out of it. So once again, I am very pro Inertia.js STEPH: It's interesting to me how different our paths have been this year where I have been working on applications that are brought on thoughtbot to then help out with some of the concerns that they have, either their application is going down, or they have a test suite that they need to improve, or there's a lot of triage that's involved. And so it makes me very excited to hear that, when you are building stuff, and it's going really well and how awesome that is. Because then I feel like most of my world has definitely been more in the triage space, which is a very interesting and fun space to be. But it brings me a lot of joy to hear about wins from let's build new stuff and hearing it be built from the ground up and how well that's going. CHRIS: Well, I'm definitely happy to provide that. But also, I want to be realistic and be like, I'm just writing next year's legacy code right now, let's be honest. I'm very happy with where we're at in this moment. But I also know how early I am in the project that I'm working on. And I'm burdened with the knowledge that I'm certain one decision that I'm making of the many that are being made I will deeply regret a year from now. I just know that that's true, and I can't let it slow me down. I got to just keep making decisions and do stuff. But I know that there's going to be one. I know that a year from now, I'm going to be like, why did we choose that option? But it's sort of the game. STEPH: [singing] We'll just know that there's something strange and your code won't change. Who are you gonna call? thoughtboters! CHRIS: Well, yes. I will definitely be calling you when I find myself in the uncertain times of legacy code of my own creation. So I look forward to that, frankly. But that's a problem for a year; I don't know, maybe two years from now. Who knows? But for now, what do you think? Let's wrap up. STEPH: Let's wrap up. The show notes for this episode can be found at bikeshed.fm. CHRIS: This show is produced and edited by Mandy Moore. STEPH: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or a review in iTunes as it really helps other people find the show. CHRIS: If you have any feedback for this or any of our other episodes, you can reach us at @_bikeshed on Twitter, and I'm @christoomey. STEPH: And I'm @SViccari. CHRIS: Or you can email us at hosts@bikeshed.fm STEPH: Thanks so much for listening to The Bike Shed, and we'll see you next week. All: Byeeeeeeeeee!!! Announcer: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.
Wszyscy czegoś się boją. Zdarza się, że nawiedzają nas koszmary i zjawy z przeszłości. Tech Writerzy nie są pod tym względem wyjątkiem. Mają swoje, nierzadko osobliwe, strachy. Z okazji Halloween rozmawiamy o tym czego boi się technoskryba i co nie daje mu spać po nocach. Uwaga: odcinek tylko dla ludzi o mocnych nerwach! Informacje dodatkowe: Grupa "Tworzenie dokumentacji" na Facebooku: https://www.facebook.com/groups/tworzeniedokumentacji Microsoft Word: https://www.microsoft.com/pl-pl/microsoft-365/word "Clippy": https://en.wikipedia.org/wiki/Office_Assistant Subversion (SVN): https://subversion.apache.org/ Git: https://git-scm.com/ "Using Branches": https://svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html Gif "Git merge": https://gifer.com/en/7h7L Git Cherry Pick: https://www.atlassian.com/git/tutorials/cherry-pick Sphinx: https://www.sphinx-doc.org/en/master/ Jamstack: https://jamstack.org/ Python: https://www.python.org/ "What is a Static Site Generator? And 3 ways to find the best one": https://www.netlify.com/blog/2020/04/14/what-is-a-static-site-generator-and-3-ways-to-find-the-best-one/ "Simplified User Interface: The Beginner's Guide": https://www.techsmith.com/blog/simplified-user-interface/ "Rethink your screenshots and tutorials with a SUI", Anton Bollen: https://www.youtube.com/watch?v=hbT5U63uKkg Micromanagement: https://en.wikipedia.org/wiki/Micromanagement Film "Kingsajz": https://pl.wikipedia.org/wiki/Kingsajz "Writing is like sorting laundry -- practical advice for tackling documentation projects": https://idratherbewriting.com/2015/01/29/writing-is-like-sorting-laundry-practical-advice-for-tackling-documentation-projects/ Podręcznik stylu (style guide): http://techwriter.pl/podrecznik-stylu-stylrecznik/ TeamCity: https://www.jetbrains.com/teamcity/ Docker: https://www.docker.com/ bash: https://pl.wikipedia.org/wiki/Bash Syndrom oszusta: https://pl.wikipedia.org/wiki/Syndrom_oszusta OpenID Connect: https://openid.net/connect/ OAuth 2.0: https://oauth.net/2/ JWT (JSON Web Tokens): https://jwt.io/ Serial comma/Oxford comma: https://en.wikipedia.org/wiki/Serial_comma Stack Overflow: https://stackoverflow.com/ "The One Where Ross Got High", Friends: https://en.wikipedia.org/wiki/The_One_Where_Ross_Got_High
В новом выпуске Витя, Макс и Саша собрались на троих что обсудить свежий радар от ThoughtWorks - (https://www.thoughtworks.com/radar). Прошлись по всем разделам, выяснили что нового, что переехало из прошлого, поделились своим отношением и опытом. Тайминг: 00:01:26 - Что за радар? 00:02:09 - Предыдущий радар на DevOps Minsk (https://www.youtube.com/watch?v=Zy6VovBkbOk) 00:05:13 - 4 основные темы радара Techniques: 00:12:15 - API extend-contract 00:12:57 - Design System 00:18:20 - Platform engineering product teams 00:20:42 - Service rotation account approach 00:26:40 - Cloud sandoxes 00:31:30 - Distroless Docker images 00:34:38 - Ethical Explorer 00:39:31 - Lightweight approach for RfC 00:43:41 - Team cognitive load 00:45:54 - Deployment drift radiator 00:50:07 - Remote mob programming 00:52:10 - GitOps 00:58:42 - Layered platform Teams 00:59:34 - Naive complexity requirements 01:03:13 - Peer review equal pull request 01:08:44 - Как происходит код ревью в больших компаниях (https://www.youtube.com/watch?v=rR4n-0KYeKQ) 01:10:07 - SAFe 01:12:54 - Separate code and pipeline ownership 01:17:00 - Ticket driven platform operating model Tools: 01:21:38 - esbuild 01:22:21 - Redash 01:23:26 - Prowler 01:24:40 - Tuple 01:27:08 - Buildah and Podman 01:30:12 - GitHub Actions 01:31:31 - Terratest 01:32:23 - Hashicorp Boundary 01:33:29 - Remote WSL 01:34:30 - AWS Pipeline Platforms: 01:37:50 - AWS Cloud Build Kit 01:42:10 - Pulumi 01:44:07 - Homemade IaC products Новости одной строкой: 01:45:50 - TeamCity goes to cloud (https://blog.jetbrains.com/teamcity/2021/04/introducing-teamcity-cloud-a-managed-ci-cd-service-by-jetbrains/) 01:46:40 - Crypto miners are killing free CI (https://layerci.com/blog/crypto-miners-are-killing-free-ci/) 01:48:07 - Fortran Package Manager (https://github.com/fortran-lang/fpm) 01:48:34 - Lens 5 Beta (https://www.mirantis.com/blog/lens-5-0-lens-spaces-beta/) 01:49:33 - Kubernetes is moving to three releases per year (https://groups.google.com/g/kubernetes-announce/c/is_pjOd5hho?pli=1) Сказать спасибо: https://www.patreon.com/devopskitchentalks Музыка: https://www.bensound.com/
Matthias is a passionate C# developer and likes to talk about build automation, productivity, testing, and tooling in general. Much of his spare time he devotes to his very own open source projects, including NUKE. He is working at JetBrains as developer advocate in the .NET department. That includes showing how awesome Rider and ReSharper are to work with. However, he is also very interested in everything around TeamCity and Kotlin. Be sure to follow Matt on Social Media https://twitter.com/matkoch87 --- Support this podcast: https://podcasters.spotify.com/pod/show/coffeandopensource/support
Co jest lepsze do pisania kodu - komercyjne środowisko programistyczne czy darmowy edytor kodu źródłowego? Czy takie porównanie w ogóle ma sens? Michał na co dzień pracuje w IntelliJ IDEA, a Paweł, jak spora część programistów, w VS Code. W tej subiektywnej rozmowie na bardzo subiektywny temat nie staramy się rozstrzygnąć, która aplikacja jest lepsza. Zamiast tego opowiadamy o tym dlaczego zaczęliśmy używać właśnie tych rozwiązań, co w nich lubimy, a co nam przeszkadza i w jakich sytuacjach według nas najlepiej się sprawdzają. Muzyka w intro oraz dźwięki pochodzą z kolekcji "107 Free Retro Game Sounds" dostępnej na stronie https://dominik-braun.net, udostępnianej na podstawie licencji Creative Commons license CC BY 4.0. Informacje dodatkowe: Stack Overflow Developer Survey 2019: https://insights.stackoverflow.com/survey/2019 Stack Overflow Developer Survey 2020: https://insights.stackoverflow.com/survey/2020 Visual Studio (VS) Code: https://code.visualstudio.com/ IntelliJ IDEA: https://www.jetbrains.com/idea/ IntelliJ IDEA - porównanie wersji Ultimate i Community: https://www.jetbrains.com/idea/features/editions_comparison_matrix.html Zintegrowane środowisko programistyczne (IDE): https://pl.wikipedia.org/wiki/Zintegrowane_%C5%9Brodowisko_programistyczne Edytor kodu źródłowego: https://pl.wikipedia.org/wiki/Edytor_kodu_%C5%BAr%C3%B3d%C5%82owego IDEs vs Code Editors: https://realpython.com/lessons/ides-vs-code-editors/ JavaScript: https://developer.mozilla.org/pl/docs/Web/JavaScript Cascading Style Sheets (CSS): https://developer.mozilla.org/pl/docs/Learn/Getting_started_with_the_web/CSS_basics React: https://pl.reactjs.org/ Node.js: https://nodejs.org/en/ Python: https://www.python.org/ Kotlin: https://kotlinlang.org/ Java: https://java.com/en/ TeamCity: https://www.jetbrains.com/teamcity/ Docker: https://www.docker.com/ Standard DITA (Darwin Information Typing Architecture): https://en.wikipedia.org/wiki/Darwin_Information_Typing_Architecture Prettier: https://prettier.io/ Szkolenie "Modern Python Projects", Sebastian Witowski: https://training.talkpython.fm/courses/modern-python-projects PyCharm: https://www.jetbrains.com/pycharm/ Language Server Protocol: https://en.wikipedia.org/wiki/Language_Server_Protocol Vim: https://pl.wikipedia.org/wiki/Vim VSCodium: https://vscodium.com/
Mike and Chris discuss the recent JetBrains FUD and ponder the impact of recent AWS policy enforcement. Plus a bunch of cool setups sent in by our audience.
Nuevos reportes incluyen el producto TeamCity desarrollado por la empresa JetBrains como el posible primer paso que utilizó Cozy Bear para comprometer la cadena de suministro del software utilizado por unas 18,000 organizaciones a nivel mundial. Si, Sunburst no se acaba y sigue dando de qué hablar.
In today's podcast we cover four crucial cyber and technology topics, including: 1. Four vulnerabilities found in Fortinet WAF 2. Software firm JetBrains denies claims of involvement in SolarWinds hack 3. British Airways set to begin settlements for 2018 breaches 4. WhatsApp to include transaction information in data shared with Facebook firms I'd love feedback, feel free to send your comments and feedback to | cyberandtechwithmike@gmail.com
In this talk, discussed about top CI/CD tools in the DevOps market segment and its major functionalities. If you are looking to use CI/CD tools for your DevOps journey, this video will be helpful for you. YouTube video link: https://youtu.be/Bs2LdCPQosU
This week on the podcast, Jeffrey is joined by Danny Vandergriff! Danny is a Principal DevOps Architect at Clear Measure, designing DevOps solutions for clients in a variety of industries. He's also done a tremendous amount of work in the area of database administration for large and complex SQL Server databases. In this episode, Danny discusses both the Dev and the Ops of DevOps! He gives advice to developers new and old to the industry; tips around designing and implementing SQL databases for business applications; his thoughts regarding disaster recovery, availability, and managing different regions in Azure SQL; recommendations for what processes .NET developers should be looking at when load testing their applications; and his thoughts on Kubernetes, TeamCity, and more! Topics of Discussion: [:38] Be sure to visit AzureDevOps.Show for past episodes and show notes. [1:01] About the recent Microsoft Build Conference and The Azure DevOps Podcast. [1:30] About today’s episode with Danny Vandergriff! [1:48] Jeffrey welcomes Danny to the show! [1:57] Danny shares his career background as well as his motivation for getting into the software industry in the first place! [2:56] Jeffrey and Danny do a synthesis of Dev and Ops. [5:10] Danny shares what he has learned from designing and implementing SQL databases for business applications. [6:38] If developers are starting new applications today, is it more common to put the database on a VM or to use the Azure SQL service? [8:43] Danny gives a rundown of the concepts that you do not have to think about with Azure SQL. [9:31] Danny explains the concept of DTU; database transaction unit. [10:26] Is there any way to autoscale the DTUs like in App Service? [10:52] Danny shares how he thinks about disaster recovery, availability, and managing different regions in Azure SQL. [11:58] A word from Azure DevOps Podcast’s sponsor: Clear Measure. [12:22] Jeffrey shares some quick announcements. [14:12] Danny’s recommendations for what process .NET developers should be looking at for load testing their applications. [15:44] Danny’s go-to recommendations for developers getting started with load testing for the first time. [17:24] Regarding new applications, until they have been formally load tested or used in a fully loaded production environment, it doesn’t scale. Is this correct? [18:28] Danny speaks about the landscape regarding build and deploy tools today and how he thinks about the different approaches. [20:10] The current state of .NET applications and Kubernetes. [21:48] Danny shares his thoughts about TeamCity. [23:23] Danny speaks about the tools and methods people should be thinking about when monitoring and supporting the applications running in production. [25:11] Danny’s favorites when it comes to starting a new application. [29:49] Danny provides his final pieces of advice for developers. Mentioned in this Episode: Azure DevOps Clear Measure (Sponsor) .NET DevOps for Azure: A Developer's Guide to DevOps Architecture the Right Way, by Jeffrey Palermo — Available on Amazon! bit.ly/dotnetdevopsebook — Click here to download the .NET DevOps for Azure ebook! Jeffrey Palermo’s Youtube Jeffrey Palermo’s Twitter — Follow to stay informed about future events! Jeffrey@Clear-Measure.com — Email Jeffrey for a free 30-point DevOps inspection (regularly priced at $5000!) — Spaces are limited! The Azure DevOps Podcast’s Twitter: @AzureDevOpsShow BlazeMeter JMeter Kubernetes TeamCity New Relic Datadog Want to Learn More? Visit AzureDevOps.Show for show notes and additional episodes.
THE NEWS FROM REDMOND Working with GitHub Issues in Visual Studio Code Visual Studio 2019 Preview Release Notes Visual Studio 2019 version 16.5 Release Notes Releasing Today! Visual Studio 2019 v16.6 & v16.7 Preview 1 Windows Package Manager Preview Introducing .NET Multi-platform App UI Blazor WebAssembly 3.2.0 now available Windows Terminal 1.0 Introducing WinUI 3 Preview 1 The Windows Subsystem for Linux BUILD 2020 Summary .NET Conf 2020 Welcome to C# 9.0 F# 5 and F# tools update Live Share, now with chat and audio support! Announcing .NET 5 Preview 4 and our journey to one .NET ASP.NET Core updates in .NET 5 Preview 4 Windows Forms Designer for .NET Core Released AROUND THE WORLD Rider 2020.1.3 and ReSharper Ultimate 2020.1.3 Bugfixes Are Here! Rider 2020.1.2 and ReSharper Ultimate 2020.1.2 Bugfixes Are Available! TeamCity 2020.1 RC is out Announcing end of support for .NET Standard 1.3 in AWS SDK for .NET Why model binding to JObject from a request doesn’t work anymore in ASP.NET Core 3.1 and what’s the alternative? Announcing Uno Platform 3.0 – Support for WinUI 3.0 Preview 1 Announcing Uno Platform 2.4 – macOS support and Windows Calculator on macOS PROJECTS OF THE WEEK CSLA CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app. This framework reduces the cost of building and maintaining applications. Also, be sure and check out the Project of the Week archives! SHOUT-OUTS / PLUGS .NET Bytes on Twitter Matt Groves is: Tweeting on Twitter Live Streaming on Twitch Calvin Allen is: Tweeting on Twitter Live Streaming on Twitch
In this episode we talk about Azure Pipelines. Definitions What is a pipeline Chain of repeatable actions/tasks that transform some input into some output. Its like a function chain. Types of pipelines Build Pipeline This pipeline takes the source code as input and produces deployable artifacts as the output. It may also do some unit testing, linting and static analysis to the code to check the validatiy of the output artifacts. Release Pipleline This pipeline takes the deployable artifacts as input and produces deployed environments as outputs. It may also perform some automated integration tests to test the validity of the deployment Continuous Integration (CI) This is the practice of merging the small batches of developer changes into the main branch continuously instead of all at once at the end of a development cycle. This is facilitated by a good build pipeline. For good or worse CI Pipeline and Build Pipeline are often conflated Continuous Delivery (CD) This is the practice of automatically deploying an artifact to an environment as soon as the artifact is created. This does not mean that the environment production. This is facilitated by a good release pipeline For good or worse CD Pipeline and Release Pipeline are often conflated CI/CD This is when we combine the practice of Continuous Integration with the practice of Continuous Delivery Continuous Deployment This is the practice of extending the automatic deployment of an artifact through all stages until is automatically deployed to production. This requires one or more good release pipelines It often gets confused with Continious Delivery. It is Continuous Delivery but Continuous Delivery is not Continuous Deployment. Azure DevOps Products Azure DevOps A suite of development tools Azure Pipelines Tool for building out the build and release pipelines Alternates Jenkins, Octopus, TeamCity, Circleci, GitLab Excellent GitHub and Azure DevOps Repos integration, but can connect to other remote repositories Excellent Azure integration, but can deploy into most any platfor or environment. Linux, macOS and Windows adjents Supports most lanuages Free for Open Source (10 parallel jobs unlimited minutes) First agent free for closed source Before Creating a Pipeline Consider your branching strategy Recommend, Trunk-based Strategy Team shares single trunk (master) that all development is based off of. Release Flow Creating a Build Pipeline YAML vs Classic Recommend, YAML uses a yaml config stored in the source code repository to define the build pipeline. Classic is good for learning the platform and can be used to figure out the correct yaml. trigger Recommend, based on changes to specified branchs can include or exclude files and folders within the branch can be triggered on a timed schedule define jobs a job us run on an agent and has its own variables and copies of source code etc. jobs can be completed in parallel define steps in jobs steps are the collection of steps/tasks that a given job will run define the task in step each step is a task this will be the heart of your build pipeline and will depend largely on what you are building variables you may want to specify some variables across jobs, like version number pools you many want to specify the type of agent to use by default instead of in every job definition Creating a Release Pipeline Classic The “only released” method for creating a release pipeline is the classic method You could create a yaml build pipeline that performed the release tasks but triggers might be more challenging. Recommend, There are some other options in pre-release. select artifacts this will likely come from artifacts published from a build pipeline
In a continuing series on DevOps, Chuck talks about build systems: what they are and why they are important to DevOps success.NOTE: The episode doesn't mention build systems by name. Three popular options are Jenkins, Travis, and TeamCity.Support the show (https://www.patreon.com/agilechuckwagon)
DevOps Nesta gravação vamos falar sobre DevOps. É um termo criado para descrever um conjunto de práticas para integração entre as equipes de desenvolvimento de softwares e operações de infraestrutura, e vamos comentar sobre algumas ferramentas de mercado também. Bora lá entender um pouco sobre o assunto? Assuntos abordados no tema O que é DevOps? Cultura DevOps Devops big data O que o DevOps tem a contribuir no desenvolvimento de software? O que é preciso para se tornar um DevOps? Como está mercado de trabalho? Metodologia e objetivos Docker e Orquestradores Integração contínua: Jenkins, Go, TeamCity; controle de versão de sistema: Team Foundation Server, Subversion, Git/Gitlab gerenciamento de configuração: Puppet Cursos e certificações Links úteis: https://gaea.com.br/6-ferramentas-devops-que-voce-precisa-conhecer/ https://www.infoq.com/br/articles/netcore-devops/?useSponsorshipSuggestions=true https://azure.microsoft.com/pt-br/overview/what-is-devops/ https://www.4linux.com.br/diferencas-entre-integracao-deploy-e-entrega-continua https://blog.caelum.com.br/integracao-continua/ https://www.infoq.com/br/news/2013/07/modelo-netflix-devops/ Participantes Jéssica Nathany (Developer e Host) Linkedin: https://www.linkedin.com/in/jessica-nathany-carvalho-freitas-38260868/ Austin Felipe (Developer e Co-Host) Linkedin: https://www.linkedin.com/in/austinfelipe/ Douglas Pires (Developer e Co-Host) Linkedin: https://www.linkedin.com/in/dpiresvilela/ Yunnes Abdul (Co-Host e Editor) Linkedin: https://www.linkedin.com/in/yunnes-abdul-ghani-2b848a32/ Ariel Cardoso (DevOps Certified | Sysadmin | Cloud (Azure/AWS) | .NET Developer) Linkedin: https://www.linkedin.com/in/arielccardoso/ Dúvidas, sugestões ou críticas envie para: debugcafe@gmail.com =)
Brant Burnett is continuously integrating and deploying microservices. This episode is sponsored by Smartsheet. Show Notes: Previous microservice episodes: Chase Aucoin on the Microservices Manifesto Richard Rodger on Microservices SOA (Service Oriented Architectures), first defined in a Gartner paper from 1996: "Service Oriented" Architectures, Part 1 CI tools mentioned: Jenkins TeamCity Travis CI AppVeyor DEB and RPM files were mentioned. DEB - Video: Anatomy of a Debian Package RPM - rpm.org Chocolatey is a similar offering for Windows s3 is a cloud storage service from AWS (Amazon) Spinnaker Blue/Green Deployment and Red/Black Deployment Canary Release Monitoring tools mentioned: Prometheus and Data Dog Linq2Couchbase is a Linq provider for Couchbase (NoSQL database). For more about Linq, check out this video featuring Ander Hejlsberg State of DevOps Report 2018 by Puppet (and Splunk) Book: Accelerate : The Science of Lean Software and DevOps by Nicole Forsgren, Jez Humble, Gene Kim LaunchDarkly Brant Burnett is on Twitter. Want to be on the next episode? You can! All you need is the willingness to talk about something technical. Music is by Joe Ferg, check out more music on JoeFerg.com!
Patrick Smacchia is building NDepend to make refactoring and technical debt decisions easier. Show Notes: The code base I used to try out NDepend is the Couchbase .NET SDK NDepend Zone of Pain, Zone of Uselessness CQLinq LINQpad TFS, TeamCity, Jenkins Pluralsight: Practical NDepend by Erik Dietrich Scott Hanselman: Exiting the Zone of Pain NDepend is on Twitter. Want to be on the next episode? You can! All you need is the willingness to talk about something technical. Theme music is "Crosscutting Concerns" by The Dirty Truckers, check out their music on Amazon or iTunes.
Eine Einführung in die kontinuierliche Integration – Continuous Integration – gibt es in der zweiundneunzigsten Episode des Anwendungsentwickler-Podcasts. Inhalt Voraussetzungen Völlig unabhängig von Programmiersprache oder Plattform. Theoretisch auch ohne separate Software umsetzbar, aber einfacher mit etablierten Lösungen wie Jenkins, Team Foundation Server, Travis CI, Teamcity oder CruiseControl. Alle Artefakte (Code, Oberflächen, Konfiguration usw.) müssen in... Der Beitrag Einführung in Continuous Integration – Anwendungsentwickler-Podcast #92 erschien zuerst auf IT-Berufe-Podcast.
React Remote Conf and Angular Remote Conf 03:18 - Dennis Ushakov Introduction Twitter GitHub JetBrains JetBrains Issue Tracker WebStorm @WebStormIDE 03:54 - Writing an IDE in Java YouTrack TeamCity 04:50 - Specs 05:43 - WebStorm Defined Integrated Development Environment (IDE) 06:19 - IDEs vs Text Editors 08:31 - Building an IDE Language Support External Tool Support Abstract Syntax Tree (AST) 13:00 - Code Reuse 15:07 - Prioritizing Features 17:11 - Why is IDE tooling important? “Code is read a lot more than it’s written.” 19:57 - Refactorings The Dynamic Nature of JavaScript TypeScript-specific Refactorings 23:35 - Next Versions of Webstorm Early Access Program 25:07 - Framework Support; Usage Data 28:12 - Other Technology and Framework Support 31:12 - Working for JetBrains 32:17 - Release Cycles and Procedures Early Access Program 34:39 - Java Source Code Contribution Kotlin Picks Jesse Kriss: Human scale technology (Jamison) React Rally (Jamison) Vote (Chuck) Transmit (Chuck) Steam Squad (Dennis) Ergobaby Four Position 360 Baby Carrier (Dennis)
React Remote Conf and Angular Remote Conf 03:18 - Dennis Ushakov Introduction Twitter GitHub JetBrains JetBrains Issue Tracker WebStorm @WebStormIDE 03:54 - Writing an IDE in Java YouTrack TeamCity 04:50 - Specs 05:43 - WebStorm Defined Integrated Development Environment (IDE) 06:19 - IDEs vs Text Editors 08:31 - Building an IDE Language Support External Tool Support Abstract Syntax Tree (AST) 13:00 - Code Reuse 15:07 - Prioritizing Features 17:11 - Why is IDE tooling important? “Code is read a lot more than it’s written.” 19:57 - Refactorings The Dynamic Nature of JavaScript TypeScript-specific Refactorings 23:35 - Next Versions of Webstorm Early Access Program 25:07 - Framework Support; Usage Data 28:12 - Other Technology and Framework Support 31:12 - Working for JetBrains 32:17 - Release Cycles and Procedures Early Access Program 34:39 - Java Source Code Contribution Kotlin Picks Jesse Kriss: Human scale technology (Jamison) React Rally (Jamison) Vote (Chuck) Transmit (Chuck) Steam Squad (Dennis) Ergobaby Four Position 360 Baby Carrier (Dennis)
React Remote Conf and Angular Remote Conf 03:18 - Dennis Ushakov Introduction Twitter GitHub JetBrains JetBrains Issue Tracker WebStorm @WebStormIDE 03:54 - Writing an IDE in Java YouTrack TeamCity 04:50 - Specs 05:43 - WebStorm Defined Integrated Development Environment (IDE) 06:19 - IDEs vs Text Editors 08:31 - Building an IDE Language Support External Tool Support Abstract Syntax Tree (AST) 13:00 - Code Reuse 15:07 - Prioritizing Features 17:11 - Why is IDE tooling important? “Code is read a lot more than it’s written.” 19:57 - Refactorings The Dynamic Nature of JavaScript TypeScript-specific Refactorings 23:35 - Next Versions of Webstorm Early Access Program 25:07 - Framework Support; Usage Data 28:12 - Other Technology and Framework Support 31:12 - Working for JetBrains 32:17 - Release Cycles and Procedures Early Access Program 34:39 - Java Source Code Contribution Kotlin Picks Jesse Kriss: Human scale technology (Jamison) React Rally (Jamison) Vote (Chuck) Transmit (Chuck) Steam Squad (Dennis) Ergobaby Four Position 360 Baby Carrier (Dennis)
Мы продолжаем цикл совместных передач с компанией Badoo. Сегодня у нас в гостях Владислав Чернов и Олег Оямяэ. Поговорим про то, как построен процесс разработки в компании. Какие инструменты используются для автоматизации создания, тестирования и деплоя релизов. Как происходит тестирование кода, собственные наработки, позволяющие быстро прогонять большое количество тестов. Что представляет собой среда разработки и как ее используют программисты компании. В выпуске: - Владислав Чернов и Олег Оямяэ кратко о себе - Процесс разработки и выкатки релизов в компании. Используемые инструменты: Git, TeamCity, JIRA, AIDA - Автоматическое тестирование в Badoo. Как прогнать 18k тестов за 3.5 минуты - Девелоперское окружение в команде, разрабатывающей сложную распределенную систему Наши гости: Владислав Чернов Олег Оямяэ Ссылки: Процесс разработки в Badoo AIDA. Автоматизация работы с Git, JIRA и TeamCity Что почитать: Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation Jenkins Continuous Integration Cookbook Continuous Integration: Improving Software Quality and Reducing Risk Podsafe: J.1.0 - Frozen Paradise
Unsupported Operation 80 Java 7u21, 5 & 6 also got new versions, despite being out of supportNew Server JRE which removes all Applet and jfx stuffSlow Train Coming - Java 8 delayed Secure the trainThe Delay of Java 8Proposed new schedule for JDK8JDK 8 Javadoc gets a light tweaking for method listingsJava 8 OptionalVirgil is a new Function/OO hybrid language for the JVM and native platforms. PLDI paper.TeamCity 7.1.5IntelliJ 12.1.2 EAP builds already showing upNetRexx 3.02RC - The Original JVM Scripting Language returnsSneaky peek at Redline Smalltalk plugin for IntelliJ IDEAJBoss Application Server renamed to WildFlyCodeMania 2013 talks appearing on YouTube ChannelGVM 1.0 releasedOpenJPA 1.2.3Wicket 6.7Derby 10.10.1.1 OpenNLP 1.5.3MRUnit 1.0.0Bloodhound 0.5.3
Сегодня обсуждаем исключительно гиковские темы. Много времени уделяем Continuous Integration и организации бизнес-процессов в команде. В выпуске: - Зачем и когда нужен Continuous Integration. CI-сервера: TeamCity, Travis CI, Jenkins. - Фильтрация строковых идентификаторов в Sphinx. - "Правильный" бизнес-процесс создания ПО. Голоса подкаста: Антон Сергеев (hackPNZ) Слава Федотов (fe.off) Антон Копылов Podsafe: J.1.0 - Frozen Paradise
Unsupported Operation Episode 71 Android Tap Keyboard - youtube demo videoOpenJDK 7 and 8 for OSX - OpenJDK 8 for Mac now with Jigsaw modules!OpenJDK 7 ported to Haiku ( screenshot )JDK8 - Selected UpdatesApple releases 2nd Java Update in 2 daysTeamCity 7.0.2 from Jetbrains.Youtrack 4.0 EAP with new Agile/Scrum board.Clojure Programming from Chas Emerick now available on Amazon Kindle.async-http-client 1.7.2 released.Built with Apache Wicket is a new tumblr blog showcasing various apps/sites built with the Apache Wicket web framework.
Unsupported Operation 65JavaJava SE 7u3 released, plus Java SE 6 Update 31 and JavaFX 2.0.3. Along with indepth specifications and documentation on the SE7 Language Spec and VM spec.EOL extended to November 2012.Other / MiscPlay 2.0 RC2 available. When asked where the webframework for Kotlin is at JFokus, JB reps said “Look at Play 2.0, we’ll make it work with Kotlin”. Good to know they’re not interested in reinventing every wheel out there.DropWizard went 0.2.0 - guys get your versions sorted!lamdaj 2.4 released - looks nice, but after using Kotlin/Xtend - these all feel too hacked on - even more so than they did before.Netty 3.3.1 released - supports SPDY, SPDY seems to be gaining traction and a call for it to be included in HTTP 2.0 has also been made.HalBuilder 1.0.1 released to Maven Central.Gerrit is now available at the Eclipse foundationJetbrainsTeamCity 7.0 RCIntelliJ IDEA 11.1 114.145 EAP new Groovy Console / REPL - doesn’t work against grails apps apparently (yet)More SVN 1.7 improvementsKotlin build tools available - Evgeny Goldin has been writing the maven plugin, which currently relies upon his ivy-plugin to download the latest kotlin from teamcity ( which exposes artifacts as an Ivy repo - NOT a maven repo ). Did we say Kotlin was open sourced?A decompiled Kotlin class shows how named parameters, nullability, and type reification works to enhance IDE support.ApacheApollo Action MQ Sub-project went 1.0 - Apollo's new threading model which is geared to multi-core microprocessors makes it faster, more scalable and more reliable than ActiveMQ and perhaps many other messaging projects.Apache Sqoop 1.4.1 incubating release - used for migrating Hadoop data between Hadoop and relational dbsApache DeltaCloud announced as top level project -Apache Deltacloud defines a RESTful Web Service application programming interface (API) for interacting with Cloud service providers and resources in those clouds in a unified manner. In addition, it consists of a number of implementations of this API for the most popular Clouds such as Amazon, Eucalyptus, GoGrid, IBM, Microsoft, OpenStack, Rackspace, and more. In addition to the API server, the project also provides client libraries for a wide variety of languages.Apache Commons Daemon 1.0.9Subversion 1.7.3Apache DeltaSpike - CDI extentions repository for Java devsHttpClient 4.2.1-betaSonatypeNexus Pro 2.0 released, adds Smart Proxies - nom! Can also now host your project documetation! - very nom.Support for NuGet repositories - let the .NET developers share the lovingGroovyGroovyFX gets a new website/url - looking nice. I see the JavaFX Scenegraph was opensourced this week as well.Grails 2.0.1 was released 80 bug fixes (they say they have been aggressively attacking bugs people reported around moving from 1.3.x)ScalaTwitter has open sourced its Effective Scala guide on Github.JBoss/RedhatJBoss AS 7.1.0 Final “Thunder” - Java EE 6 Full Profile CertifiedGoogleAndroid 5.0 “Jelly Bean” reportedly by June 2012 - Maybe for ONE handset.....CloudBees posted a good article on doing Continuous Integration of Android apps in the cloud.Calabash - automated functional testing of Android AppsTech preview of Chromium with Dart engine built in now available. Let the fragmentation begin!MiscMicrosoft’s new logo is FOUR BLUESCREENS - respecting their heritage ;-)
Unsupported Operation - Final for 2011Java / Oracle / Tool / Language RelatedJava 7u2 released, ships with JavaFX 2.0.2 which was also released JavaFX 2.0 - Intro By Example is available on Kindle as well - didn’t realize there any books out on this.Java 6u30 also releasedeFX is a new JavaFX/Netbeans Platform frameworkNetBeans 7.1 RC1 releasedJetBrains released IntelliJ IDEA 11 - a bugfix update to TeamCity was also released last weekGoogle’s Eclipse plugin is now open sourceOrion, Eclipses Cloud IDE has gone 0.4 M1 - new and noteworthy include HTML syntax highlighting, Code Mirror syntax highlighting (including mixed-mode documents, such as htmll/javascript/php), syntax validation, content type service (to store different mime types), and much moreState of the LambdaJSR 292 Goodness: Almost static final fields - for the language level hackersJSR 352 passes with two no votes - Batch JSRRedline Smalltalk compiler “complete” - work on the runtime begins. Why Smalltalk on the JVM?Dart on ChromiumShaftServer is a new DartVM Application Server - jHiccup is a new performance monitoring/analysis tool released under Creative Commons from Azul SystemsHP open source webos Interesting that they’re asking the community to decide/recommend licensing, governance etc.Adobe joins the OSGi Alliance Board of Directors ( Adobe’s Felix Meschberger apointed to BOD - principal developer/driver of the Apache Felix OSGi container ).Web Server / Web FrameworksPrimeFaces Mobile 0.9 - JSF optimized for mobilesOracle releases Weblogic 12c - which finally does full J2ee6 Apache Geronimo goes full J2EE 6 certifiedJetty 8 got released without much fanfare. Its available as standalone download, maven artifacts, rpm and debian packagesJersey 1.11 released with Eclipse MOXy supportApache Wicket 1.5 releasedRestfuse 1.0 has been released - its a test framework for REST apis running with junit.DropWizard - REST framework from Coda Hale / Yammer - has nice heartbeat system for built-in monitoring/testingMiscHibernate 4.0 FinalHibernate Search 4.0 FinalBook: Practical Unit Testing with TestNG and Mockito - available Q1 2012Mockito 1.9 released Awesomely improved documentation Pax Exam 2.3 has been releasedConfluence 4.1 releasedJDBC driver for Neo4j from Rickard OburgGoogle Guava 11rc1 out - changesAndroid+Antur Kotwal is heading to Auckland on Janurary 5 to talk about new ICS APIs.ICS shipping to Nexus S devices over the next week or twoSpringSpring Social 1.0.1Spring 3.1GroovyGrails 2.0 Heroku announces “native” support for Grailsgroovy 2.0 roadmap outlined modularity! no more swing in your server app!ScalaAdopts Play framework as officialScala IDE for Eclipse gets an updateTypesafe has been in damage control over recent high profile Scala dissing - introduces a paid for service that protects you against binary incompatibility, all the rest of you have to sufferScala+GWT compiler has gone to version 3, seems to be following Scala’s trend of changing a lot of the internalsAnd a summary of the Yammer debateEclipseXtend 2.2 released with standalone compiler, ant task, maven plugin.Apache MavenMaven 2.x Release Plugin - Version 2.2.2 Fixed problems with version numbers in profiles not being updated, updated to SCM 1.6Maven Dependency Plugin - Version 2.4 Minor changes but one HUGE improvement: Add to purge-local-repository goal ability to clean only snapshotsdependencypath-maven-plugin Sets a property pointing to the artifact file for each selected project dependency. Each property name will have a base name in form of groupId:artifactId:type:[classifier][.relative][.suffix]. This is similar to the /dependency:properties/ goal but with additional features, like setting a relative path and filtering.Maven Surefire Plugin, version 2.11 Includes changes to the proposed plugin APIMaven FindBugs Plugin version 2.3.3Mock Repository Manager version 1.0-alpha-1 The Mock Repository Manager suite of projects are used to provide mock or lightweight Maven Repository Managers for use during integration testing of Maven plugins.Still no Apache Maven 3.0.4 release, rolled to rc4 after several issues were found, awaiting a re-release of Wagon to increase HTTP timeouts before rerolling rc5.
Enregistre le 11 mai 2010 David Gageot http://blog.javabien.net Algodeal http://www.algodeal.com/ Subversion http://subversion.apache.org/ Git http://git-scm.com/ Mercurial http://mercurial.selenic.com/ Bazaar http://bazaar.canonical.com/en/ github http://github.com/ Express Board http://express-board.fr/ GitX http://gitx.frim.nl/ plug in forrest de mercurial http://mercurial.selenic.com/wiki/ForestExtension Git est MacGyver et Mercurial est James Bond (un peu obsolete): http://importantshock.wordpress.com/2008/08/07/git-vs-mercurial/ TeamCity http://www.jetbrains.com/teamcity/ Infinitest http://improvingworks.com/products/infinitest/ Serverless Continuous Integration with Git http://blog.javabien.net/2009/12/01/serverless-ci-with-git/ Hudson http://hudson-ci.org/ http://kohsuke.org/category/infradna/ MySQL http://www.mysql.fr/ H2 database http://www.h2database.com GitK http://www.kernel.org/pub/software/scm/git/docs/v1.6.0.6/gitk.html TortoiseHg http://tortoisehg.bitbucket.org/ TortoiseGit http://code.google.com/p/tortoisegit/ IntelliJ http://www.jetbrains.com/idea/ Eclipse JGit http://eclipse.org/jgit/ BitBucket http://bitbucket.org/ Gist http://gist.github.com/ Pastebin http://pastebin.org/ Pro Git http://progit.org/ Git Community Book http://book.git-scm.com/ One commit at a time http://www.gitready.com/ Git Magic http://www-cs-students.stanford.edu/~blynn/gitmagic/ Linus talks about Git http://www.youtube.com/watch?v=4XpnKHJAok8 Nous contacter Contactez-nous via twitter http://twitter.com/lescastcodeurs sur le groupe Google http://groups.google.com/group/lescastcodeurs ou sur le site web http://lescastcodeurs.com/
Podcast na téma IDEA 7.0, TeamCity, Domain Specigic Languages a další zajímavosti od firmy JetBrains. Tento podcast je speciální v tom, že jsme do něj premiérově zařadili soutěž o jednu licenci IntelliJ IDEA 7.0. Tu předá host tohoto podcastu Václav Pech na prosincovém CZJUGU. Vaše ohlasy uvítáme zde v diskusi a nebo na naší mailové adrese czpodcast zavináč gmail.com. Poděkování: výsledný záznam pro vás zpracoval mistr zvuku Kolísko.