# GitHub DevSecOps Part 2: Creating a Simple Project and Your First Workflow

> Part 2 of the GitHub DevSecOps series. Patrick Steger and I create a private GitHub repository for a Java Spring Boot app, enable Actions, and build a two-workflow pipeline that compiles the code and runs the unit tests.

- Date: 2023-01-11
- Source: https://romanoroth.com/en/blogs/github-devsecops-creating-a-project/
- Tags: DevSecOps, GitHub, CI/CD, DevOps, GitHub Actions, Workflows, Spring Boot, Pipeline


Before we plug security tools into anything, we need a repository, a pipeline, and a working build. In Part 2 of our GitHub DevSecOps series, Patrick Steger and I create a private GitHub repo for a small Java Spring Boot service, enable GitHub Actions, and wire up a two-workflow pipeline that compiles the code and runs the unit tests. This is the skeleton everything else in the series hangs on.

<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
			<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/6ZdxXDu8ZDA?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
		</div>


## The Application We're Building Around

We use the same simple Java Spring Boot application throughout the series — a web service that returns "Spring is here!" plus a unit test that calls the service and verifies the response. Small enough to read in one screen, real enough to demonstrate every DevSecOps tool we will add over the next ten sessions.

## Prerequisites and Licensing

GitHub can be used as SaaS in the cloud or installed on premise via GitHub Enterprise. The thing to know up front: if you want a **private** repository **and** the **Advanced Security** features, you need an Enterprise license. We are going to use both, so that is what we run on. If you only need public repositories, the free tier covers a lot.

## Creating the Repository

Sign in, click **New**, and you get the option to import an existing repo or start fresh. We start fresh. Owner is our enterprise account. Repository name is `DevSecOpsDemo`. Visibility is private. We skip the README, `.gitignore`, and license templates for the demo, but in a real project you absolutely want them.

Once the repo exists, take a quick tour of the tabs:

- **Code** — the repository itself
- **Issues** — basic issue tracking; works for backlog management too
- **Pull requests** — covered in a later session
- **Actions** — where our pipelines live
- **Projects** — lightweight project management
- **Wiki** — code documentation
- **Security** — the tab we will use heavily for SAST, SCA, secret scanning
- **Insights** — contributor stats and the dependency graph
- **Settings** — repo configuration

## Enabling Actions Safely

If the **Actions** tab is missing, head to **Settings → Actions → General** and enable Actions there. Worth pausing here, because this is the first real security decision you make on a GitHub project.

Actions are small custom applications. They are usually code you did not write, running inside your pipeline, with potential access to secrets. You get four levels:

1. Allow every action from the marketplace
2. Allow only enterprise actions
3. Allow enterprise actions plus a specific allowlist
4. Disable actions

From a pure security standpoint, the safest model is "enterprise actions only" — review the community actions you want, copy them into your enterprise space, security-review them, and use those copies. For this demo we accept everything to keep moving, but in an enterprise environment you should not.

## Importing the Code

Back to the **Code** tab → **Import code**. We point GitHub at our existing project, wait a moment, and the source tree shows up: the Spring Boot application under `src/main/java`, the controller that returns "Spring is here!", and the tests under `src/test`.

## Two Workflows: Main Pipeline and Build Pipeline

GitHub calls pipelines **workflows**, and they live in `.github/workflows/`. We split our pipeline into two files on purpose: a **main pipeline** that orchestrates everything, and a **build pipeline** it calls. Splitting workflows keeps each file small and lets you reuse the build pipeline from other workflows later.

Create `.github/workflows/main-pipeline.yml`. Tip: GitHub's file editor lets you type slashes in the filename to create folders inline. The main pipeline gets a clear, numbered name (`00 - Main CI/CD Pipeline`), triggers on `push` to `main` (with sensible path-ignore filters) and on `workflow_dispatch` so we can run it manually, and defines a `build` job that calls our `build.yml` and forwards the secrets it needs.

Numbered names — `00 - Main`, `10 - Build` — sound trivial but they make the Actions UI readable when you have a dozen workflows running side by side. Recommended.

Next file: `.github/workflows/build.yml`. Name it `10 - Build Pipeline`. Triggers are `workflow_dispatch` (run manually) and `workflow_call` (callable from another workflow — this is what main-pipeline uses).

The build job declares the permissions it needs, runs on `ubuntu-latest`, and chains a series of steps that each call an **action**. The actions: check out the source with `actions/checkout@v3`, set up Java, compile with Maven, prepare an output directory, run the tests, prepare the test result directory, upload the application binary as an artifact, upload the test results as a downloadable zip, and publish the test results into the GitHub UI.

Commit both files to `main` and head over to **Actions**.

## Watching the Pipeline Run

The Actions tab shows the main pipeline kicking off and the build pipeline running underneath it — the numbered names line them up neatly. Click in and you get a summary page: total duration, status, jobs executed, three tests found, the application binary and test results listed as artifacts (downloadable as zip), and the test results rendered inline. Click the build job and the full log is right there.

## Where Actions Come From

We used `actions/checkout@v3` without much explanation. That comes from the **GitHub Marketplace**, the place to discover Actions. The Checkout action is provided by a **verified creator** — GitHub vouched for them. Verified creators are your safer choice. Even safer: copy a verified action's source into your enterprise repo, security-review it, and consume it from there. That is the model you want when production code depends on it.

## Key Takeaways

1. **Pick the licensing tier that matches what you want to build.** Private repos plus Advanced Security need GitHub Enterprise. Decide upfront — it shapes everything else.

2. **Enable Actions deliberately, not by default.** The "allow everything from the marketplace" option is convenient and risky. In an enterprise context, "enterprise-only" plus a curated allowlist is the right baseline.

3. **Workflows live in `.github/workflows/`.** That folder is the entire pipeline configuration surface. Knowing it exists is half the battle.

4. **Split workflows for orchestration and reuse.** A main pipeline that calls a build pipeline (via `workflow_call`) keeps each file small and lets you compose larger pipelines later without rewriting the build.

5. **Use a naming scheme like `00 - Main`, `10 - Build`.** It looks pedantic until you have ten workflows. Then it is the only thing that keeps the Actions UI readable.

6. **Use verified Actions, or import them into your enterprise.** Marketplace Actions run inside your pipeline with access to your secrets. Treat them as third-party code. Verified creators are the floor; enterprise-imported and reviewed copies are the ceiling.

