Top tip for breaking writer’s block

My top tip for getting out of writer’s block is: Move to a different medium, temporarily. Yesterday I was struggling to get started with some writing, and I remembered that this strategy often works for me. So I tried it. It worked again!

By “moving to a different medium”, I mean opening a text editor and jotting my thoughts there, or writing on a scratch pad, or simply opening a page that is completely separated from the work that I’m trying to complete.

When I’m trying to write something, there are two decisions I need to make:

  • What do I want to say?
  • Where should I put it?

Sometimes the two decisions are so intertwined that my brain gets in a loop. I start writing, then I think, “Wait, this shouldn’t go here.” So I delete what I’ve written. But then I realise that I do need to write it, and start again, and … loop. Then I spend time trying to figure out where the content should go, which makes me lose my thread of thought and lose impetus.

This destructive loop can happen in any type of writing. Most recently, it happened to me when I was providing detailed feedback in a doc review. I wanted to help the author with the syntax and correctness of the content, but the work also needed higher-level input on the structure of the page as a whole and its location in the doc set. I started putting my feedback on the page itself, but some of the feedback was too high level to belong on the page, or so I thought. So I removed what I’d written. But then there was nowhere to put that feedback, and I lost time trying to figure out how to give the feedback rather than focusing on what the feedback actually should be.

I was stuck. I went for a walk to clear my head. In the middle of my walk, I remembered what’s worked before! I moved out of the doc review tool into a text editor and jotted down my feedback as it came to me, without trying to decide where it belonged. When I’d finished, it was easy to slot the pieces of feedback into the right place.

This type of writer’s block can happen when you’re writing a book (“should this content be in the book, or is it more like plot and character notes for me, or should it be in the blurb?”) or a technical document (“does this content belong in this doc or another doc, or should I split the doc, or does it belong in a blog post?”) and so on..

Moving to a different format or medium gives my brain the freedom to write what I need to say. After that, it’s relatively easy to decide where the content should go.

Live streaming with StreamYard to record presentation and webcam view

I’ve recently started a YouTube channel called Soothing Musings with Sarah. I’ll tell you a bit about the channel itself later. First, though, I want to share what I learned about how to record a presentation alongside a webcam view of myself. After quite a bit of investigation, I found that the best combination of services for my needs is StreamYard, Google Slides, and YouTube.

For my video format, I wanted to include a mini window showing myself talking. I therefore needed an app that would record a webcam view. Alongside the talking me, I wanted a main window showing pictures of the thing I was talking about. For the main window, I decided a slide deck would be best, so that I could include text as well as photos. So, I needed an app that would record a slide presentation, as well as the mini window of me as presenter.

Here’s the end result:

I already had a Gmail account, which gives me access to Google Slides for presentations, and YouTube for sharing videos.

Getting started with Google Slides and YouTube

You can get help from the Google documentation on how to set up an account. You can use the same account for Gmail, Google Slides, and YouTube. There’s also information on how to create presentations with Google Slides.

Setting up a named YouTube channel

When you set up a YouTube account, you automatically get a YouTube channel that has the same name as your account. For my videos, I wanted a channel with a specific name: Soothing Musings with Sarah. YouTube calls a named channel a brand account (or sometimes just an account). A brand account doesn’t need to be a business account.

The YouTube docs describe how to set up a named channel. One thing to note is that there may be a 24-hour delay before your new named channel is available. I found there was no delay for my default YouTube channel, but the delay did occur for the named channel (brand account) which I created.

StreamYard for recording of presentation and webcam view

StreamYard gives you a browser-based streaming studio. I’m using Chrome as my browser. StreamYard works by streaming your recorded video directly to YouTube. All you need to do is set up your screen layout and other options in StreamYard, then record the session. As soon as you finish the session, you can watch your video on your YouTube channel. StreamYard gives you a link to the video on YouTube, which you can find on the StreamYard dashboard.

After you finish recording your video on StreamYard, YouTube still needs to complete some post-processing, which can take a few hours. When that’s done, your video becomes visible in the list of videos in your YouTube channel. That’s also when you can set the video thumbnail and download the video. Note that you can view the video on YouTube immediately after finishing the session on StreamYard, even before YouTube’s post-processing is finished.

Connecting StreamYard to YouTube

Here’s how to connect StreamYard to your YouTube channel:

  1. Sign up for a StreamYard account. StreamYard offers free and paid plans.
  2. In StreamYard, go to the destinations page. As you can see in this screenshot, I currently have two destinations set up in Streamyard: one for my default YouTube account, and one for my brand account. Your destinations page is probably empty at this point:
  3. Click Add a Destination.
  4. On the next page, click YouTube Channel:
  5. Follow the prompts to sign in to Google and to choose your account or brand account. Make sure you use the email address that you used to set up your YouTube channel.

When that’s all done, you’re ready to create your first recording, which StreamYard calls a broadcast.

Recording your session on StreamYard

The following steps include some tips that I gleaned while experimenting with StreamYard. They may not all apply to you, but they’ll at least help you get started.

  1. Get ready to be filmed. 🙂 Brush your hair, arrange your collar, do whatever you need to do to make yourself feel comfortable. Of course, you can choose not to include a webcam view in the recording. In that case, as you were.
  2. Go to the StreamYard broadcasts page and click Create a Broadcast:
  3. If StreamYard prompts you with a dialog window named Broadcast to, choose the YouTube channel that you want as the destination for your video recording.
  4. Set the title, description, and privacy for your video. I like to set the video to private at first, so that I can review it before the general public can see it:
  5. Click Create Broadcast.
  6. Check the view from your camera and the sound from your mic, as prompted by StreamYard.
  7. Set a display name. This is the text that appears on the bottom left of the webcam view. Looking at the video at the top of this post, you can see that my display name is Sarah Maddox, and it shows up as white text on an indigo background.
  8. This is when you enter the StreamYard studio. It looks like this:
  9. Take some time to examine the options, in particular the various settings available in the strip on the right-hand side of the studio. In the above screenshot, I’ve selected the Brand option, which is where you can set your brand colour etc. Some of the options are available in the paid plans only. For my brand colour, I chose indigo, which is why my display name has an indigo background. You can find some good colours on the material design website.
  10. If you want a recording of yourself to be part of the video, click the box with the webcam view near the bottom left of the studio page. That’s the box that shows a moving picture of you. By clicking the box, you add the webcam view to the video.
  11. Check the angle of your video camera, and make sure the webcam shows just what you want it to show.
  12. Now it’s time to set up the layout of your video. Click one of the layouts that appear in a row like this:

    I like the layout that shows 2 people on the left plus the presentation on the right. That’s the one highlighted in the above screenshot. Even though I’m showing only one person (that is, one webcam view) I like the sizing ratios in this layout.
  13. Move over to your Google Slides deck, and click Present then Presenter view, so that you can use the presenter view window to drive the presentation:

  14. You’ll see a presenter view window that looks something like this:
  15. In StreamYard, click the Share Screen, option, which appears at the bottom of the StreamYard studio:

  16. Choose the option to share the Chrome tab and select the presenter view for your presentation:

  17. Bring the presenter view window for your presentation to the fore, and drag the presenter view window to a convenient position, so that it doesn’t cover any bits of the StreamYard screen that you want to see while presenting. In particular, make sure you can see the “Go Live” button. The “End Broadcast” button will appear in the same place when you’re actually broadcasting, and you’ll want to find that easily.
  18. Now it’s time to start the recording. In StreamYard, click Go Live at the top right of the studio window:

  19. Click Go Live again to confirm that you’re ready. This starts the streaming to YouTube. (It’s OK! If you’ve set the privacy option to private, no-one but you can see the video while you’re streaming or even when you’ve finished.)
  20. Press Alt+Tab (or Cmd+Tab) to bring the presenter view to the fore again.
  21. Go for it! Have your say and show your slides.
  22. When you’re ready to stop recording, click End Broadcast at top right of the StreamYard studio:

  23. Click End Broadcast again to confirm. Wait a second or so until StreamYard lets you know that it’s closed the stream.
  24. Take a look at your video! In StreamYard, you can click Links at top right of the studio window, then click View on YouTube:

  25. Alternatively, you can click Return to Dashboard and see your list of recorded videos on the Past Broadcasts tab:
  26. Click the three dots next to each recording to see various options, including the option to view the video on YouTube.

You can also see the video directly from YouTube. In your channel, Click Your videos then select Live streams from the dropdown list:

  • After some hours, the video appears in the Uploads list too.
  • In YouTube Studio, the recording appears on the Live tab.
  • Note that the Download link for the video in YouTube Studio doesn’t work immediately — it’s greyed out. It took a few hours for me before the link became active.

Other hints:

  • While recording in StreamYard, you can remove the webcam window but retain audio: Click the layout option that shows just the full screen. You can then put the webcam back again by choosing your original layout option.
  • The StreamYard docs are excellent, including a good set of FAQ.

Other services that I tried

I tried a few other services to get the layout that I needed. When live streaming with YouTube Live, I couldn’t share my screen. ScreenCastify is very easy to use and produces nice results, but I couldn’t get the onscreen camera box (webcam view) to appear when in presenter mode with Google Slides. 

My channel: Soothing Musings with Sarah

My YouTube channel is a new type of communication for me. I’m attempting to use voice mixed with beautiful pictures of nature, plus a soupçon of information, to convey a sense of calm. Hence, Soothing Musings with Sarah. At this point, the channel has a couple of videos streamed via StreamYard. I’m experimenting as I go. There’ll probably be more to come.

If you’re investigating how to record a video with a camera view and a slide deck, I hope you find this post useful.

What is Git cherry picking and how do you use it?

“Cherry pick a commit”. I’ve heard the phrase often. It sounds kind of endearing, yet scarily technical at the same time. What is cherry picking and why would you want to do it? One fine day I found that I needed it, and suddenly I appreciated the what and the why. So I figured out the how. I hope this post will help you towards the same understanding.

Here’s the scenario: I’d applied a change to the latest version of the Kubeflow docs. Specifically, the change added a banner and associated logic to inform readers if they’re reading an archived version of the docs. Now I needed to copy the same banner and logic to the older (archived) versions of the docs.

More details of the scenario

The screenshot below shows the banner that I wanted to add to all the archived versions of the docs:

The way we store archived versions of the Kubeflow docs is to make a branch of the current version (that is, a branch from the master). For example, here’s v0.6 of the docs, for which the source is in this branch on GitHub. The master branch contains the current version of the docs.

I’d added the banner and accompanying logic to the master branch in this pull request (PR). Now I needed to copy the code to all the archived branches. I didn’t want to have to copy/paste all my changes into the relevant files in every affected branch.

Enter cherry picking.

Picking sweet cherries

It’s useful to know that, when you’re using GitHub, cherry picking a commit is equivalent to cherry-picking a PR. GitHub squashes all the commits in a PR into a single commit when merging the PR into the code base.

What does a cherry-picked PR look like? No different from any other PR. It’s a collection of changes that you want to make, pointing to the branch on which you want to make them. For example, PR #1550 is a cherry pick of PR #1535, with a few extra changes added after cherry picking.

Below are the steps that I figured out to prepare and do the cherry picking. One thing to note in particular is that I had to do something different if my fork of the repository already contained a copy of the branch into which I intended to cherry pick.

The first step is to check out the master branch, which contains the updates that I want to copy to the archive branches:

git checkout master

Make sure my local working directory is up to date, by pulling all content from the remote master branch. (I’m working on a fork of the Kubeflow website repository. The convention is to give the name upstream to the repository from which you forked.)

git pull upstream master

Get a log of commits made to the master branch, to find the commit that I want to cherry pick:

git log upstream/master

A commit name consists of a long string of letters and numbers. Let’s say that I need the commit named e895a107edba5e68cc0e36fa3a05a687e806cc19.

Check to see which branches I have locally:

git branch -v

Also check my fork on GitHub to see which branches I already have there.

Now I’m ready to prepare the first archived branch for cherry picking. Let’s say I start with the version 0.6 branch of the docs, named v0.6-branch. If I don’t already have the branch on my fork, I need to get a copy of the branch from the remote master, and then push that copy up to my fork, so that I have a clean slate to apply the cherry pick to. So, I pull the branch down to my local working directory then push it up to my fork. In this example, the branch name is v0.6-branch:

git checkout master
git pull upstream v0.6-branch:v0.6-branch
git checkout v0.6-branch
git push origin v0.6-branch

(I’m working on a fork of the Kubeflow website repository. By default, the name of your fork of the repository is origin.)

In the cases where I do already have the branch on my fork, I need to copy the branch from my fork down to my local working directory, check that the branch is up to date by fetching updates from the main repository, then push the branch back up to my fork. In this example, the branch name is v0.5-branch:

git fetch origin v0.5-branch:v0.5-branch
git checkout v0.5-branch
git status
git fetch upstream v0.5-branch
git push origin v0.5-branch

Now I’m ready to cherry pick the changes I need. Remember, I’m cherry picking from master into an archive branch. Let’s say I want to cherry pick into the v0.6-branch:

git checkout v0.6-branch
git cherry-pick e895a107edba5e68cc0e36fa3a05a687e806cc19

The long string of letters and numbers is the name of the commit, which I obtained earlier by running git log.

The changes are now in my local copy of the branch. I can make extra changes if I want to. (For example, in my case I needed to update some metadata that relates specifically to the branch, including an archive flag used in the logic that determines whether to display the banner on the doc pages.)

When I’m happy with the cherry-picked updates and any other changes I’ve made, I push the updated branch up to my fork:

git push origin v0.6-branch

Then I create a PR and specify the base branch to be the name of the branch into which I’m cherry picking the changes. In the case of the above example, the base branch should be “v0.6-branch”. The screenshot below shows the base option, currently pointing to “master”, on the GitHub UI when creating a PR:

Can the cherries turn sour?

In the above scenario, I used cherry picking to apply a change going backwards in time. The requirement was to apply an update to older versions of the docs, which as a rule we don’t update very often. I didn’t cherry pick from a feature branch into the master branch. There are plenty of warnings on the web about things that could go wrong when you cherry pick. I found this post by Rob Friesel helpful in providing context in a non-scary way.

How did I make the banner itself?

That’s another story. 🙂

How to add a banner to website pages using Hugo

A while back, I needed to display a banner on every page of a documentation website. Furthermore, I wanted the banner to appear only under specific conditions. We use Hugo as the static site generator for the website. Here’s what I figured out, using Hugo templates.

I wanted to add a banner to the archived versions of the Kubeflow documentation, such as v0.7 and v0.6, letting readers know that they’re viewing an unmaintained version and pointing them to the latest docs.

Here’s an example of such a banner:

In Kubeflow’s case, the purpose of the banner is to catch people who enter the archived documentation from a web search and make sure they realise that a more up-to-date set of docs is available.

Summary: Adding a banner to a page with Hugo templating

In essence, you need to do the following:

  • Figure out which Hugo layout file is responsible for the base layout of your pages. In the case of the Kubeflow docs, the responsible layout file is at layouts/docs/baseof.html. You can see an example of the layout file in the Docsy theme: layouts/docs/baseof.html. (Kubeflow uses Docsy on top of Hugo.)
  • Add the code for your banner to the layout file. Or, even better, create a partial layout, often called just a partial. A partial is a snippet of code written in Hugo’s templating language. Put the code for your banner into the partial, then call the partial from the base layout. For the Kubeflow version banner, the code sits in a Hugo partial named version-banner.html.

There’s an explanation of the code later in this post.

Making the banner’s appearance conditional

In order to offer docs for multiple versions of Kubeflow, we have a number of websites, one for each major version of the product. The overall configuration of the websites for the different versions is the same. For example, we have the current Kubeflow documentation, and archived versions 0.7 and 0.6.

I wanted to make sure we had to do only minimal extra configuration to cause the banner to appear on the archived doc sets. I didn’t want to have to edit the layouts each time we create an archive. A good solution seemed to be a parameter that we can set in the site’s configuration file.

How it works – first the configuration settings

The parameter that controls the appearance/non-appearance of the banner is named archived_version. If the parameter is set to true, the banner appears on the website. The parameter value is false for the main doc site, kubeflow.org. When we create an archived version of the docs, we set the parameter to true.

The parameter is defined in the site configuration file, config.toml. The configuration file also contains a version number and the URL for the latest version of the docs. Both these fields are used in the banner text.

Here’s a snippet showing the relevant part of the configuration file:

# The major.minor version tag for the version of the docs represented in this
# branch of the repository. Used in the "version-banner" partial to display a
# version number for this doc set.
version = "v1.0"

# Flag used in the "version-banner" partial to decide whether to display a
# banner on every page indicating that this is an archived version of the docs.
archived_version = false

# A link to latest version of the docs. Used in the "version-banner" partial to
# point people to the main doc site.
url_latest_version = "https://kubeflow.org/docs/"

How it works – the content and logic

For the Kubeflow website, a Hugo layout file is responsible for the base layout of the documentation pages:layouts/docs/baseof.html. You can see an example of the layout file in the Docsy theme: layouts/docs/baseof.html. (Kubeflow uses Docsy on top of Hugo.)

I inserted the following line into the base layout:

{{ partial "version-banner.html" . }}

The above line calls a Hugo partial named version-banner.html. The partial contains the banner content and logic. (I’ve contributed the logic for the version banner to Docsy, which is why the URL leads to the Docsy repository.)

Below is a screenshot of the content of the partial. Unfortunately I can’t paste the code, because WordPress strips out all HTML:

You can copy the code from the partial: version-banner.html.

The code does the following:

  • Check the value of the archived_version parameter. If true, continue to the next step.
  • Get the value of the url_latest_version parameter, for use in the banner content when giving readers a link to the latest version of the docs.
  • Get the value of the version parameter, for use in the banner content when showing readers the version of the website that they’re viewing.
  • Create an HTML div containing the styling and content for the banner.

Here’s the screenshot of the banner again, so that you can compare it to the HTML div:

Docs or it didn’t happen

I created a user guide for other people who want to use the banner logic on their sites using the Docsy theme: How to display a banner on archived doc sites.

I also updated the release procedures for the Kubeflow engineering/docs team, explaining that we must set the archived_version parameter to true when archiving a website version.

In closing

I hope this post is useful to you, if you find that you need to add a banner to a website using Hugo templating!

How to remove an updated file from a PR on GitHub

This is my third post about GitHub techniques that aren’t necessarily obvious to those of us who think in non-Git terminology. This post derives from the fact that I searched the internet for “remove file from PR” and was led astray by helpful people telling me how to use Git to delete a file.

Say you changed the content of a file by mistake, and to your surprise the file has become part of your set of changes tracked by Git, and has thus become part of your pull request (PR). Now you want to remove the file from the PR. You don’t want to delete the file itself, you just want to revert the inclusion of the file in the PR. (Because, if you delete the file, then that deletion becomes part of your change set, which is not what you want at all.)

The basic principle is: Undo the changes that you made to the file, to make the file disappear from the PR.

Assumptions:

  • The instructions below assume that you have not yet merged the PR into the GitHub repository. If you have merged the PR, then you should revert the PR and create a new PR with just the updates you need.
  • The instructions below assume that the unwanted updates are in a file that already exists in the GitHub repository. If the unwanted updates are in an entirely new file that you created, then you can delete the file from your file system, then run git rm <file path> followed by git commit to remove the file from the PR.

Note: Save your updates if you need them. If you still need the updates that you made to the file,  perhaps to include in another PR, copy and save the updates somewhere outside your Git working area. You’ll lose the updates when you follow the steps described below.

Removing the updates manually

You can remove the updates manually, by copy-pasting the original contents of the file into your version of the file.

  1. Find the original version of the file, either on your fork if you forked from the main repository, or on the repository from which you cloned your local repository.
  2. Copy the entire content of the file and paste it into your copy of the file.
  3. Commit the new changes if necessary:
    • If you had not yet committed your unwanted changes, then you don’t need to do any more.
    • If you’d already committed your unwanted changes, create another commit now. The new commit wipes out your previous changes.
    • If you’d already pushed the changes up to a remote repository, push the new commit now too.

Using git to remove the updates

Case 1: You haven’t yet committed the unwanted updates to your local repository.

Run the following command if you want to undo the updates in your working directory and you haven’t yet committed the unwanted updates:

git restore <file-name-including-path>

Case 2: You’ve committed the unwanted updates to your local repository but you haven’t yet pushed the unwanted updates to your remote repository.

By default, you have a remote repository named origin, which is the repository from which you cloned your local copy of the files.

If you haven’t pushed the unwanted updates to the remote origin repository, you can retrieve the file contents from the origin repository.

The following sequence of commands assumes that the master branch in the remote repository named origin contains the unchanged version of the file. This is the case if you have not pushed your unwanted changes up to origin master.

git fetch origin master
git checkout origin/master -- <file-name-including-path>
git commit -m "Reverted content of file."

Example of the checkout command:

git checkout origin/master -- docs/my-file.md

Case 3: You’ve already pushed the unwanted updates to your remote origin repository.

In this case, you may be able to retrieve the file contents from your upstream repository.

If you’re working on a fork of a repository, the convention is to give the name upstream to the repository from which you forked. You can run the following command to see which remote repositories Git knows about:

git remote -v

Name the upstream repository now if you haven’t already named it. In the following example, replace <project> with the GitHub project name and <repository> with the repository name within the project:

git remote add upstream https://github.com/<project>/<repository>.git

Run the following commands to retrieve the file content from the upstream file:

git checkout upstream/master -- <file-name-including-path>
git commit -m "Reverted content of file."

That’s all, folks

I’ve tried out all these commands myself, and they do what I expect them to do. Let me know if they do what you wanted to achieve too!

Here are my other two posts about Git and GitHub:

%d bloggers like this: