Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Copilot Instructions for OpenTofu ORAS Fork

## Project Overview

This is a **fork** of [opentofu/opentofu](https://github.com/opentofu/opentofu) that adds an **ORAS backend** for storing OpenTofu state in OCI registries (Docker, GHCR, ECR, etc.).

## Branch Strategy

```
main → Synchronized with opentofu/opentofu:main (tracking only, do not commit here)
develop → Main development branch (all PRs target here)
```

### Branch Rules

| Branch | Purpose | Commits |
|--------|---------|---------|
| `main` | Tracks upstream opentofu/opentofu | Only via sync-upstream workflow |
| `develop` | All fork development | Via Pull Requests |

### Workflow

1. **Sync upstream**: `sync-upstream.yml` runs daily and when new upstream tags are detected
2. **PR to develop**: Creates PR `🚀 Release vX.Y.Z` from `main` → `develop`
3. **Review & merge**: Manually merge the PR (resolve conflicts if any)
4. **Auto-release**: `auto-release.yml` creates tag `vX.Y.Z-oci` and GitHub Release
5. **Build**: `release-fork.yml` builds binaries for all platforms

## Release Naming Convention

Fork releases follow upstream versions with `-oci` suffix:

- Upstream: `v1.12.0`
- Fork: `v1.12.0-oci`

This allows users to choose which upstream version they want with ORAS support.

## Key Directories

### ORAS Backend (main contribution)

```
internal/backend/remote-state/oras/
├── backend.go # Backend implementation
├── client.go # OCI registry client
├── state.go # State management
├── locking.go # Distributed locking
├── versioning.go # State versioning
├── README.md # Detailed documentation
└── *_test.go # Tests
```

### Fork-specific files (not in upstream)

```
.github/
├── copilot-instructions.md # This file
├── release.yml # Release notes configuration
├── labeler.yml # PR auto-labeling rules
└── workflows/
├── release-fork.yml # Fork release workflow
├── sync-upstream.yml # Upstream sync automation
├── auto-release.yml # Auto-tagging on merge
└── labeler.yml # PR labeler workflow
```

## Development Guidelines

### Creating PRs

1. Always target `develop` branch
2. Use descriptive titles for release notes generation
3. Apply appropriate labels (auto-labeler will help):
- `oras`, `oci`, `backend` - ORAS backend changes
- `enhancement`, `feature` - New features
- `bug`, `fix` - Bug fixes
- `documentation` - Docs changes
- `ci` - CI/CD changes

### Commit Messages

No strict format required, but be descriptive. Examples:
- `Add compression support to ORAS backend`
- `Fix lock acquisition race condition`
- `Update CI workflows for develop branch`

### Testing

```bash
# Run ORAS backend tests
go test ./internal/backend/remote-state/oras/...

# Run all tests
go test ./...
```

## Files to NEVER modify on develop

These files should only change via upstream sync:

- `LICENSE`
- `CHARTER.md`
- `GOVERNANCE.md`
- Core OpenTofu code (unless fixing integration with ORAS)

## Labels for Release Notes

PRs are automatically categorized in releases based on labels:

| Label | Category |
|-------|----------|
| `enhancement`, `feature` | 🚀 Features |
| `bug`, `fix` | 🐛 Bug Fixes |
| `oras`, `oci`, `backend` | 📦 ORAS Backend |
| `security` | 🔒 Security |
| `documentation` | 📚 Documentation |
| `test` | 🧪 Tests |
| `maintenance`, `chore` | 🔧 Maintenance |
121 changes: 121 additions & 0 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Auto Release

on:
pull_request:
types: [closed]
branches:
- develop

Comment on lines +3 to +8
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow lacks concurrency control, which could lead to issues if multiple release PRs are merged simultaneously or in quick succession. Multiple concurrent runs could create duplicate tags or conflicting releases. Consider adding a concurrency group to ensure only one auto-release operation runs at a time.

Copilot uses AI. Check for mistakes.
permissions:
contents: write

jobs:
create-release:
name: Create release on merge
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.title, '🚀 Release v')
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: develop

- name: Extract version from PR title
id: version
run: |
# Extract version from PR title "🚀 Release v1.2.3"
PR_TITLE="${{ github.event.pull_request.title }}"
VERSION=$(echo "$PR_TITLE" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
Comment on lines +27 to +29
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regex pattern to extract version from PR title is fragile and could match partial version numbers. For example, if the title contains 'v1.12.0-alpha' it would only extract 'v1.12.0'. Consider making the pattern more robust by ensuring it matches the complete version string or by adding word boundaries.

Suggested change
# Extract version from PR title "🚀 Release v1.2.3"
PR_TITLE="${{ github.event.pull_request.title }}"
VERSION=$(echo "$PR_TITLE" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
# Extract version from PR title like "🚀 Release v1.2.3" or "🚀 Release v1.2.3-alpha+build.1"
PR_TITLE="${{ github.event.pull_request.title }}"
VERSION=$(echo "$PR_TITLE" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?')

Copilot uses AI. Check for mistakes.
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=${VERSION}-oci" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"

- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Create and push tag
run: |
TAG="${{ steps.version.outputs.tag }}"
git tag -a "$TAG" -m "Release $TAG"
git push origin "$TAG"

- name: Create GitHub Release
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda # v2.2.1
with:
tag_name: ${{ steps.version.outputs.tag }}
name: ${{ steps.version.outputs.tag }}
generate_release_notes: true
draft: false
prerelease: false
body: |
## OpenTofu ${{ steps.version.outputs.version }} + ORAS Backend

This release is based on [OpenTofu ${{ steps.version.outputs.version }}](https://github.com/opentofu/opentofu/releases/tag/${{ steps.version.outputs.version }}) with the ORAS backend for OCI registry state storage.

### ORAS Backend Features

- 📦 Store state in any OCI-compatible registry (GHCR, ECR, ACR, Docker Hub, etc.)
- 🔒 Distributed locking support
- 📜 State versioning with configurable retention
- 🗜️ Optional gzip compression
- 🔐 Compatible with OpenTofu state encryption

### Quick Start

```hcl
terraform {
backend "oras" {
repository = "ghcr.io/your-org/tf-state"
}
}
```

See [ORAS Backend Documentation](https://github.com/${{ github.repository }}/blob/develop/internal/backend/remote-state/oras/README.md) for full configuration options.

---

**Full Changelog**: See auto-generated release notes below.

notify-conflict:
name: Create issue on conflict
if: github.event.pull_request.merged == false && startsWith(github.event.pull_request.title, '🚀 Release v')
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Extract version from PR title
id: version
run: |
PR_TITLE="${{ github.event.pull_request.title }}"
VERSION=$(echo "$PR_TITLE" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
echo "version=$VERSION" >> $GITHUB_OUTPUT

- name: Create conflict issue
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const version = '${{ steps.version.outputs.version }}';
const prNumber = ${{ github.event.pull_request.number }};

await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `⚠️ Release ${version} requires manual intervention`,
body: `The release PR #${prNumber} was closed without merging.

This may indicate:
- Merge conflicts that need manual resolution
- The PR was intentionally closed

### Action Required

1. Check PR #${prNumber} for details
2. If conflicts exist, resolve them manually
3. Re-run the sync workflow or create a new release PR

/cc @${context.repo.owner}`,
labels: ['release', 'needs-attention']
});
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
push:
branches:
- main
- develop
- 'v[0-9]+.[0-9]+'
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ on:
push:
branches:
- main
- develop
- 'v[0-9]+.[0-9]+'
- checks-workflow-dev/*
tags:
Expand Down
90 changes: 0 additions & 90 deletions .github/workflows/govulncheck.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Label PR by size
uses: codelytv/pr-size-labeler@56f6f0fc35c7cc0f72963b8571fabd12128e252c # v1.10.1
uses: codelytv/pr-size-labeler@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_label: 'size/XS'
Expand Down
Loading
Loading