Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
161123 stories
·
33 followers

Marketing ops as code: Automating events from planning to follow-up on GitHub

1 Share

I run marketing for GitHub in Japan and Korea, and events are the heartbeat of it: a recurring webinar series for enterprise developers, community meetups in Tokyo, invite-only executive sessions in Seoul. What does a developer in this market actually need right now? Which topics are worth an hour of their time, and who should be in the room? I’d happily spend all day on those questions.

What follows the decisions is another matter. Once an event is greenlit, a fixed sequence begins:

  • Duplicate a landing page on our event platform.
  • Generate a set of UTM-tagged links: one for each channel, each formatted just so.
  • Draft the invitation email and file a request with the team that sends it.
  • Add the event to two project boards.
  • Every morning until the event: download the registrant list, clean it up, post a status update for stakeholders.
  • After the event: export the attendees, reshape the list for a CRM upload, tag the right records, and write a report.

While none of these tasks are hard on their own, they’re an opportunity to paste the wrong link, skip a day, or misspell a campaign name that 15 downstream reports depend on.

Here’s the thing: I used to be an engineer. My first career was keeping databases alive on Linux servers for enterprise customers. While my coding may be rusty, I can still see a pipeline begging to be automated. This is where I put GitHub Copilot to use and where you could too in your own work.

So I didn’t write the code. I wrote down my runbooks, handed them to GitHub Copilot, and grew the automation in conversation. Today, an event I used to assemble by hand over a couple of days sets itself up from a single GitHub Issue, screens its own registrants every morning, and cleans up after itself when it’s over.

This post walks through how that works, and why I think anyone whose job involves repetitive work across tools that offer any scriptable way in (an API, or even just a CLI) can do the same.

An event is an issue

I can’t claim the foundational idea as my own. Marketing teams at GitHub already had a habit of opening one GitHub Issue per project. This becomes the place where the plan, the discussion, and the status live together. The issue was already our unit of work. What I did was make the issue do the work.

Three GitHub primitives carry the whole system:

  • Issue forms are the application form. Instead of a blank text box, an issue form presents structured fields: event title, date, region, campaign name, target audience. We have one form per event type, such as webinars and in-person events, and they feed the same machinery.
  • Labels are the switches. A label like event-setup isn’t a tag, it’s a trigger. Each automation workflow starts with a condition that says, in effect, “only run when this label is present.”
  • Actions are the machinery. GitHub Actions workflows fire when labels land, parse the form fields out of the issue body, and go do the work.

Everything a repository gives developers, it gave my marketing workflow for free: history, visibility, review, and a URL for every decision.

One thing made this possible, and it has nothing to do with events specifically: our event management platform exposes an API. Our CRM doesn’t even need one; its official CLI covers everything we do, and I never configured an API key for it, because the CLI signs in through the browser and handles authentication from there. API or CLI, the requirement is the same: a scriptable way in. If your repetitive work runs through a tool that offers either an event platform, a CRM, a form builder, an analytics service, the pattern in this post applies to you.

A developer reading this may already be composing the obvious objection: isn’t this reinventing the wheel? Marketing automation platforms exist, and a good one might have covered some of this out of the box. But APAC is less one market than a collection of very different ones, and even within my own team, workflows shift with each sub-region and each segment. The same webinar might run in Japanese for Tokyo one month and in Korean for Seoul the next, with different segments, different fields in the CRM, and a different definition of a good lead. Getting a packaged tool to absorb all of those variations means customization budgets, consulting hours, and waiting on someone else’s roadmap. Building it ourselves, from the tools already at hand, means a workflow change is a pull request: I describe what I want, a reviewer checks it, and it lands on the main branch through exactly the process developers use to change software.

Planning an event is a conversation

The pipeline starts before the Issue exists. I open GitHub Copilot and say, roughly: “I want to run a webinar about AI-assisted development in November.”

What happens next is shaped by a file called AGENTS.md at the root of our repository. It’s our team runbook, written in plain Markdown, that defines how we name campaigns, how fiscal quarters map to dates, which time zone each region uses, and what a good invitation email looks like. GitHub Copilot reads it, and then, it finds a similar past event, proposes a campaign name that follows our naming rules, drafts two versions of the invitation email, and asks me the questions the runbook says to ask.

Putting a conversation at the front of the pipeline was itself a design decision, and it solved two problems at once. Automate everything, and you lose flexibility; the day you want this one event to be slightly different, a rigid pipeline has no place to say so. But if you let humans fill in everything, you get mistakes. The conversation sits exactly between the two. GitHub Copilot follows the template, so the data that lands in the Issue is the right data in the right format. And because it’s a conversation, I can bend the details for this one event without breaking the machinery downstream.

When we started, this conversation happened in GitHub Copilot CLI, in a terminal. That was fine for me, but “open a terminal” is a barrier for many people I’d love to bring into this workflow. With the GitHub Copilot app, the same conversation now happens in a regular desktop window. The barrier to entry dropped from “comfortable with a shell” to “can type.”

I want to be precise about the division of labor, because it’s the whole point: GitHub Copilot drafts; I decide. Every campaign name, every email subject line, every date gets my sign-off before anything moves. At the end of the conversation, GitHub Copilot files the GitHub Issue with the right labels, and that’s when the machines take over.

One label, one event, fully staged

The moment the event-setup label lands on the issue, a GitHub Actions workflow picks it up and does, in a few minutes, what used to take me the better part of a day:

  • Duplicates a past event on our event platform to create the new landing page
  • Generates the full set of UTM-tagged URLs: one per channel, consistently formatted, every time
  • Produces the invitation email as a Word document and commits it to the repository
  • Opens request Issues with the teams that send emails and track regional marketing
  • Adds the event to our project boards and fills in the fields
  • Posts a summary comment back on the Issue, so the next human who opens it sees everything in one place

Registration screening runs on a schedule instead of a label. Every morning, a cron-triggered workflow fetches the latest registrants for every open event and shares the cleaned-up list. For invite-only events, it also screens the waitlist against our criteria (is this registrant a developer at an enterprise account, a student, or a competitor who would very much like to attend our executive briefing?) before anyone gets approved.

The design decision I’m most proud of is a single on/off switch called DRY_RUN, stored as a setting (in GitHub terms, a repository variable) that every workflow checks before it runs. Flip it on, and every workflow goes through the motions without touching any external system: no landing pages created, no issues filed in other repositories, no lists shared. When you’re a team of marketers automating your own job, you need a way to rehearse. DRY_RUN is the rehearsal switch, and it’s the reason I was never afraid to experiment.

After the event, a slash command

Post-event work used to be the worst part: exporting attendees, reformatting columns for the CRM upload, matching company names against account records, and writing the report. Now it’s two commands.

/lead-upload fetches the attendee list, shapes it into the exact format our marketing operations team needs for a CRM upload, files the request Issue, and closes out the tracking issues. /event-report pulls attendance metrics and survey results and posts a report as a comment on the event’s Issue, back to the one URL where everything about this event lives.

These are GitHub Copilot agent skills, and here is the part I most want you to hear: a skill is a Markdown file. Each one is a SKILL.md: a written procedure, in prose, that tells GitHub Copilot what to do, in what order, and what to watch out for. Mine read like the runbooks I used to keep in my head, because that’s what they are.

If you can write a runbook, you can write a skill.

Skills are also what keeps the system flexible. No two markets in the Asia/Pacific (APAC) region run their follow-up identically. Audiences differ, segments differ, local conventions differ, and a hard-coded workflow would force every market into one shape. A procedure written in Markdown is flexible: each market can adapt the runbook to its own reality without touching the machinery underneath. That is precisely why the post-event steps live in GitHub Copilot skills rather than in fixed pipelines.

We treat skills like code in one respect: new ones arrive by pull request and get reviewed before they’re merged, with a CODEOWNERS file routing the review to a maintainer. Marketing automation with an approval process. The governance came free with the platform, too.

Built-in guardrails let me experiment

I automated a workflow that touches customer data and API credentials, in a repository my whole team can see, while barely writing code myself. Six months ago I would have said that combination was reckless. What changed my mind was realizing how many guardrails were already in place before I showed up.

Some guardrails I built: the DRY_RUN switch, a test suite that runs on every pull request, and code review for every change. Standard developer habits. It turns out they protect marketing work just as well as they protect software.

But the guardrails that mattered most came with the platform:

  • Secret scanning with push protection. The nightmare scenario for someone in my position is committing an API token by accident. GitHub’s push protection blocks the push before the secret ever lands in the repository, and for GitHub’s own tokens, even one that does slip through gets revoked automatically.
  • GitHub Copilot’s data policies. Registrant lists are business data, and the fixed scripts handle them in fixed ways. But real work is never entirely fixed; some days I need a one-off cut of the data that no script anticipates. Because GitHub Copilot’s business plans don’t retain prompts or use them to train models, I could ask for that one-off analysis directly, instead of doing what people all over the industry quietly do: pasting business data into whatever consumer chatbot is open in the next tab. The same goes for the models themselves: which ones I can use at all is set by organization policy, not left to my personal judgment, so even a one-off experiment runs inside boundaries the company has already decided. The safe path and the easy path were, for once, the same path.

One more thing the skills made possible, almost as a side effect: because each procedure is now a named, fixed unit of work, I can match the model to the job, choosing from the lineup our organization has approved. A fast, inexpensive model handles the daily list-cleaning; a stronger one drafts campaign copy.

And one honest failure, so you don’t repeat it: the morning screening workflow once failed silently for five days before anyone noticed the lists had gone stale. Automation you don’t monitor is more of a time bomb with a delay. Give every scheduled workflow a way to complain loudly so you don’t miss it.

Start with one task

Here’s what I’d suggest, from one recovering manual-worker to another.

Pick the single most repetitive task in your week. Then check whether the tools it touches have an API or a CLI. You may be surprised how many do.

Then build the smallest possible version: an issue form that captures the inputs, a label that means “go,” and an Action that does one step of the work. Or skip straight to writing your runbook down as a SKILL.md and let GitHub Copilot execute it. Run it with a dry-run switch until you trust it. Grow it from there.

I didn’t write the code. I wrote down what I already knew (how the work gets done) and the platform did the rest. Whatever your version of the morning registrant list is, it’s probably one written-down runbook away from doing itself.

Get started:

The post Marketing ops as code: Automating events from planning to follow-up on GitHub appeared first on The GitHub Blog.

Read the whole story
alvinashcraft
just a second ago
reply
Pennsylvania, USA
Share this story
Delete

Migration: SQL Server to Azure SQL Managed Instance using DMS

1 Share

Moving SQL Server to Azure SQL Managed Instance sounds challenging on day one. It doesn't have to be. If your backup files already sit in an Azure Blob Storage container, Azure Database Migration Service (DMS) handles the rest. I am going to sharing the quick and easy to follow steps for online migration to Azure SQL Managed Instance.

What do you need first?

  1. Target SQL Managed Instance
  2. Contributor on the managed instance and storage account, Reader on their resource groups, Owner or Contributor on the subscription if you're creating a new DMS instance.
  3. Microsoft.DataMigration registered in your subscription - one time step
  4. A dedicated storage account, with backups organised: "One folder in root" per database, and one backup per file.
  5. Network configuration of Azure Storage account should allow communication with the Target SQL Managed Instance.

How does DMS reach your backups?

1) The portal lists your backup files using your signed-in account / identity, so grant yourself Storage Blob Data Reader on the container.

2) Then choose how DMS itself reads them:

OptionHow to set it upNote
Managed identity (recommended)

a) Managed instance → Security > Identity, switch "ON" the System assigned managed identity or add User assigned managed identity.

b) Then storage account → Access control (IAM) → assign Managed identity in step a), Storage Blob Data Reader permission.

Refer: DMS - Support for Managed Identity for Azure SQL Managed Instance migration | Microsoft Community Hub
SAS key

Ensure that the storage account has the "Allow storage account key access" enabled.

Rotate the key once you're done

Run the migration

  1. Portal → Azure Database Migration Service → select or create an instance.
  2. Select Start migration.
  3. Set target = Azure SQL Managed Instance, backup location = Azure Blob Storage, mode = Online.

     

     

  4. Enter your source SQL Server details, then pick the target subscription, resource group and instance.

     

  5. Point to the storage account, container and folder. Rename the target database here if you want.

     

  6. Select Next to review the summary and Start migration.

Monitor, then cutover

Watch the DMS dashboard for monitoring the migration job and click on it. As backup files move Arrived → Restoring → Restored. Ignored means a file isn't part of a valid backup chain. Keep uploading backups until you're ready for cutover.

Cutover steps:

Cutover is your only downtime, so schedule it in advance with your application owners:

  1. Stop incoming transactions 
  2. Take a final backup into the same container.
  3. Set the source database to read-only.
  4. Confirm every backup shows Restored, then select Complete cutover.

     

  5. And repoint the Application to the managed instance. (Ensure to fix the login, users mapping and permissions)

When the status reads succeeded, you're running on Azure.

Know before you go

  • A migration job runs for a maximum of 30 days, then cancels and deletes the target database.
  • DMS won't overwrite a database on Target that already exists on the target.
  • DMS, Azure blob container and Target SQL Managed Instance should be part of the same region and subscription.
  • You must place backup files for different databases in separate folders inside the container. And folder should be present in the root of the container.
  • The following server objects aren't supported:
    SQL Server Agent jobs
    Credentials
    SSIS packages
    Server audit
  • If you're migrating to a SQL Managed Instance in the Business Critical service tier, account for the delay in bringing the databases online on the primary replica while they're seeded to the secondary replicas.

 

Read the whole story
alvinashcraft
34 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Trump on AI Extinction: Beating China Is the Bigger Concern

1 Share

Trump dismisses AI extinction warnings and says beating China is the priority as researchers and lawmakers call for stronger safeguards on advanced systems.

The post Trump on AI Extinction: Beating China Is the Bigger Concern appeared first on TechRepublic.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

DeepSeek Launches V4.1-Flash With Lower Memory and API Costs

1 Share

DeepSeek V4.1-Flash promises lower memory use and API costs, but buyers should test its performance, compatibility and total deployment expenses.

The post DeepSeek Launches V4.1-Flash With Lower Memory and API Costs appeared first on TechRepublic.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

What to Use the Latest AI Tools For

1 Share
From: AIDailyBrief
Duration: 28:27
Views: 719

Eight new product launches land in a single week, from OpenAI's GPT Live voice API to Cognition's Swe-2 model to persistent projects in Cursor. NLW goes through each one with a practical read on who should actually use it and what for, plus why voice control and cost-optimized model stacks are the two trends running underneath all of them. In the headlines: Anthropic's misuse report detailing distillation attacks, Sam Altman signaling openness to a coordinated slowdown, OpenAI pausing Pro subscriptions over compute, and Microsoft tripling data center capacity.

The AI Daily Brief helps you understand the most important news and discussions in AI.
Subscribe to the podcast version of The AI Daily Brief wherever you listen: https://pod.link/1680633614
Get it ad free at http://patreon.com/aidailybrief
Learn more about the show https://aidailybrief.ai/

Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

IoT Coffee Talk: Episode 330 - "Remember" (Let Freedom Ring)

1 Share
From: Iot Coffee Talk
Duration: 1:02:46
Views: 28

Welcome to IoT Coffee Talk, where hype comes to die a terrible death. We have a fireside chat about all things #IoT over a cup of coffee or two with some of the industry's leading business minds, thought leaders and technologists in a totally unscripted, non-AI affected and manipulated, organic format.

This week Rob, Bill, Pete, and Leonard jump on Web3 for a discussion about:

🎶 🎙️ BAD KARAOKE! 🎸 🥁 "Sweet Home Alabama", Lynyrd Skynyrd
🐣 Where were we on 9/11 and what did we remember about tech?
🐣 The revolution in the dismantling of privacy rights in the last 25 years.
🐣 How the advertiser became your best and untrustworthy friend.
🐣 [INSERT NAME], would you like to buy my junk?
🐣 What do we think about Jason Coxon's doomsaying? Is he credible?
🐣 How Los Angeles became Miami.... the art of irrigating people.
🐣 How the dismantling of our privacy led to our surveillance society.
🐣 Remembering 9/11 and our moment of silence to the heroes.
🐣 How do we stop our journey on the AI road off the cliff of our existence?
🐣 What will be the societal impacts of building mansions (data centers) for AI?
🐣 Why trust is more important as AI expands its influence and application.
🐣 Why the AI evangelist could be the most dangerous person in your organization.
🐣 Apple's iPhone Surface Duo. What did the guys think?

It's a great episode. Grab an extraordinarily expensive latte at your local coffee shop and check out the whole thing. You will get all you need to survive another week in the world of IoT and greater tech!

Tune in! Like! Share! Comment and share your thoughts on IoT Coffee Talk, the greatest weekly assembly of Thinkers 360 and CBT tech and IoT influencers on the planet!!

If you are interested in sponsoring an episode, please contact Stephanie Atkinson at Elevate Communities. Just make a minimally required donation to www.elevatecommunities.org and you can jump on and hang with the gang and amplify your brand on one of the top IoT/Tech podcasts in the known metaverse!!!

Take IoT Coffee Talk on the road with you on your favorite podcast platform. Go to IoT Coffee Talk on Buzzsprout, like, subscribe, and share: https://lnkd.in/gyuhNZ62

Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories