Core Concepts

NoShip is built around a few key primitives: freeze windows, rules, schedules, overrides, and an audit trail. This page explains each one.

Freeze Windows

A freeze window is a time-bounded period during which merges and/or deployments are blocked. Every freeze window has:

  • Name -- a human-readable label (e.g. “Q4 Release Freeze”).
  • Status -- one of scheduled, active, completed, or cancelled.
  • Start and end time -- when the freeze activates and deactivates. A “quick freeze” starts immediately with no set end time (you cancel it manually).
  • Rules -- one or more rules that define what is blocked (see below).

When a freeze window is active, NoShip sets a failing commit status check on pull requests that match its rules. If deployment blocking is configured, it also rejects deployment protection rule requests.

Freeze Rules and Glob Patterns

Each freeze window can have one or more rules. A rule defines:

  • Block type -- what to block:
    • merge -- blocks pull request merges only
    • deployment -- blocks deployments only
    • both -- blocks merges and deployments
  • Repository pattern (repo_pattern) -- a glob pattern matched against the full repository name (e.g. org/repo-name).
  • Branch pattern (branch_pattern) -- a glob pattern matched against the branch name the PR targets.
  • Environment pattern (environment_pattern) -- a glob pattern matched against the deployment environment name.

All patterns default to * (match everything). A PR or deployment must match all three patterns in a rule to be blocked.

Glob Pattern Examples

# Block all repos
repo_pattern: *

# Block repos matching a prefix
repo_pattern: myorg/api-*

# Block a specific repo
repo_pattern: myorg/billing-service

# Block only the main branch
branch_pattern: main

# Block release branches
branch_pattern: release/*

# Block production environments
environment_pattern: prod*

# Block staging and production
environment_pattern: {staging,production}

Multiple Rules

A freeze window can have multiple rules. A PR or deployment is blocked if it matches any rule. This lets you create a single freeze that covers different scopes:

Rule 1: block_type=merge,  repo_pattern=myorg/api-*,  branch_pattern=main
Rule 2: block_type=both,   repo_pattern=myorg/web-app, environment_pattern=production

In this example, merges to main are blocked for all API repos, and both merges and deployments are blocked for the web-app production environment.

Block Types

NoShip supports two enforcement mechanisms:

  • Merge blocking -- NoShip posts a failure commit status check on pull requests. When configured as a required status check in branch protection, this prevents the PR from being merged.
  • Deployment blocking -- NoShip rejects deployment protection rule requests from GitHub. GitHub natively enforces the block: the deployment cannot proceed while the rule is active.

You can use merge, deployment, or both on each rule depending on your needs. Many teams block merges during feature freezes and block deployments during maintenance windows.

Recurring Schedules

Schedules let you create freeze windows automatically on a recurring basis. A schedule defines:

  • Name -- a label for the schedule.
  • RRULE -- an iCalendar recurrence rule (RFC 5545) that defines the recurrence pattern.
  • Duration -- how long each generated freeze window lasts, in minutes.
  • Timezone -- the timezone for the schedule (defaults to your organization setting).
  • Default rules -- the block type, repo pattern, branch pattern, and environment pattern applied to each generated freeze.

RRULE Examples

# Every Friday at 3:00 PM
FREQ=WEEKLY;BYDAY=FR;BYHOUR=15;BYMINUTE=0;BYSECOND=0

# Every weekday at 6:00 PM
FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;BYHOUR=18;BYMINUTE=0;BYSECOND=0

# First day of every month at midnight
FREQ=MONTHLY;BYMONTHDAY=1;BYHOUR=0;BYMINUTE=0;BYSECOND=0

# Every two weeks on Friday at 4:00 PM
FREQ=WEEKLY;INTERVAL=2;BYDAY=FR;BYHOUR=16;BYMINUTE=0;BYSECOND=0

Schedules can be toggled on or off. When active, NoShip automatically creates freeze windows at the specified times. You can preview upcoming occurrences from the schedule detail page.

Emergency Overrides

Sometimes you need to merge or deploy during a freeze -- for example, to ship a critical hotfix. NoShip supports emergency overrides with an approval workflow.

How Overrides Work

  1. Request -- A team member requests an override, specifying the freeze window, a reason, and optionally a specific repo, environment, or PR number.
  2. Review -- An admin or owner reviews the request and approves or denies it.
  3. Use -- Once approved, the override is valid for a limited time (configurable TTL, default 60 minutes). The requester can merge or deploy the specific PR or to the specified environment.
  4. Expire -- After the TTL expires or the override is used, it becomes inactive. Each override is single-use.

Override Scoping

Overrides can be scoped to:

  • A specific repository (e.g. myorg/api-service)
  • A specific environment (e.g. production)
  • A specific PR number -- this creates a single-PR bypass

If no scope is specified, the override applies to the entire freeze window.

Audit Trail

Every action in NoShip is logged to an immutable audit trail. Audit entries include:

  • Action -- what happened (e.g. freeze.created, override.approved, schedule.toggled)
  • Actor -- who performed the action (GitHub username)
  • Resource -- what was affected (freeze window, schedule, override)
  • Repository -- if applicable, which repo was involved
  • Details -- additional context (rule changes, override reasons, etc.)
  • Timestamp -- when the action occurred

You can filter the audit log by action type, repository, date range, and actor from the dashboard. Audit retention depends on your plan (free: 7 days, team: 90 days, business: 365 days).