
JetBrains Space: A Unified Development Environment
β οΈ Important Update: As of May 31, 2025, JetBrains has discontinued support and sales for Space. This comprehensive guide remains valuable for existing users and serves as a historical reference for understanding advanced DevOps platform design principles.
Table of Contents
- Quick Start Setup
- Key Features Deep Dive
- The JetBrains Space Philosophy
- Hands-On: Repository Management
- Mastering Code Reviews in Space
- Space Automation: CI/CD with Kotlin DSL
- Package Management & Registries
- Team Collaboration Features
- IDE Integration Mastery
- Advanced Workflows & Best Practices
- Migration Strategies
- GitHub vs. JetBrains Space
- Troubleshooting Common Issues
- Performance Optimization
- Data Export and Migration
- FAQ
- Conclusion
Quick Start Setup
Initial Space Configuration
Before diving deep, letβs get you set up with a complete JetBrains Space environment:
# 1. Create your Space organization (via web interface)
# Navigate to: https://jetbrains.space/
# 2. Install JetBrains Toolbox (if not already installed)
# Download from: https://www.jetbrains.com/toolbox-app/
# 3. Configure Git for Space
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
# 4. Set up Space-specific Git configuration
git config --global space.organization "your-org-name"
git config --global space.token "your-personal-token"
Essential IDE Setup
// .space/settings.kts - Space project configuration
job("Setup Environment") {
container("openjdk:11") {
env["SPACE_TOKEN"] = Params("space.token")
env["GRADLE_OPTS"] = "-Dorg.gradle.daemon=false"
shellScript {
content = """
echo "Setting up JetBrains Space environment..."
./gradlew clean build --no-daemon
"""
}
}
}
Key Features Deep Dive
1. Git Hosting & Advanced Repository Management
Space provides enterprise-grade Git hosting with powerful branching strategies and repository management.
# Advanced Git operations in Space
# Create and configure a new repository
git init my-space-project
cd my-space-project
# Set up Space remote
git remote add origin https://git.jetbrains.space/your-org/project/my-space-project.git
# Configure advanced branching strategy
git config branch.main.mergeoptions --no-ff
git config branch.develop.rebase true
# Set up pre-commit hooks for Space
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
# JetBrains Space pre-commit validation
./gradlew spotlessCheck detekt
if [ $? -ne 0 ]; then
echo "Code quality checks failed. Please fix issues before committing."
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
2. Sophisticated Code Review Workflows
// .space/code-review.kts - Automated code review setup
reviewPolicy {
// Require at least 2 reviewers for main branch
requireReviewers(
branch = "main",
minReviewers = 2,
requiredReviewers = listOf("tech-lead", "senior-dev")
)
// Auto-assign reviewers based on file patterns
autoAssignReviewers {
filePattern("*.kt", "*.java") assignTo listOf("kotlin-team")
filePattern("*.sql") assignTo listOf("database-team")
filePattern("*.yml", "*.yaml") assignTo listOf("devops-team")
}
// Require passing builds before merge
requirePassingBuilds = true
// Block self-approval
allowSelfApproval = false
}
3. Professional Issue Management System
// .space/issues.kts - Issue templates and automation
issueTemplate("bug-report") {
title = "π Bug Report: [Brief Description]"
description = """
## Description
A clear description of what the bug is.
## Steps to Reproduce
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Expected Behavior
What you expected to happen.
## Actual Behavior
What actually happened.
## Environment
- OS: [e.g. iOS]
- Browser: [e.g. chrome, safari]
- Version: [e.g. 22]
## Additional Context
Add any other context about the problem here.
""".trimIndent()
labels = listOf("bug", "triage-needed")
assignees = listOf("qa-team")
}
issueTemplate("feature-request") {
title = "β¨ Feature Request: [Brief Description]"
description = """
## Is your feature request related to a problem?
A clear description of what the problem is.
## Describe the solution you'd like
A clear description of what you want to happen.
## Describe alternatives you've considered
Alternative solutions or features you've considered.
## Additional context
Any other context or screenshots about the feature request.
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3
""".trimIndent()
labels = listOf("enhancement", "product-review")
}
The JetBrains Space Philosophy
JetBrains Space embodies a developer-first, unified workspace philosophy. Unlike fragmented toolchains, Space provides seamless context preservation across all development activities.
Core Design Principles
- IDE-Centric Workflow: Every operation should be performable from within the IDE
- Zero Context Switching: Minimize cognitive load by keeping all tools in one place
- Type-Safe Configuration: Use Kotlin DSL instead of error-prone YAML
- Intelligent Automation: Leverage IDE intelligence for CI/CD and code analysis
Target Organizations
graph TB
A[JetBrains Space Ideal Users] --> B[JetBrains IDE Heavy Users]
A --> C[Enterprise Teams 10-500 developers]
A --> D[Polyglot Development Teams]
A --> E[DevOps-Mature Organizations]
B --> B1[IntelliJ IDEA Users]
B --> B2[PyCharm Teams]
B --> B3[WebStorm Projects]
C --> C1[Need Unified Toolchain]
C --> C2[Complex Project Dependencies]
C --> C3[Compliance Requirements]
D --> D1[Java/Kotlin + Frontend]
D --> D2[Python + Data Science]
D --> D3[Full-Stack Applications]
Hands-On: Repository Management
Advanced Repository Configuration
// .space/repository.kts
repository {
name = "enterprise-application"
description = "Core enterprise application with microservices"
// Branch protection rules
branchProtection {
pattern = "main"
rules {
requirePullRequest = true
requireCodeOwnerReviews = true
requireUpToDateBranch = true
requiredStatusChecks = listOf(
"continuous-integration",
"security-scan",
"performance-tests"
)
}
}
// Code owners configuration
codeOwners {
globalOwners = listOf("@architects", "@tech-leads")
rules {
path("src/main/kotlin/**") ownedBy listOf("@kotlin-team")
path("src/main/resources/db/**") ownedBy listOf("@database-team")
path("infrastructure/**") ownedBy listOf("@devops-team")
path("docs/**") ownedBy listOf("@tech-writers")
}
}
}
Multi-Repository Project Setup
# Set up a mono-repo style project with Space
mkdir enterprise-platform && cd enterprise-platform
# Initialize main repository
git init
git remote add origin https://git.jetbrains.space/company/platform/enterprise-platform.git
# Create submodule structure
git submodule add https://git.jetbrains.space/company/platform/user-service.git services/user-service
git submodule add https://git.jetbrains.space/company/platform/order-service.git services/order-service
git submodule add https://git.jetbrains.space/company/platform/shared-library.git libs/shared
# Configure submodule update strategy
git config submodule.recurse true
git config diff.submodule log
git config status.submodulesummary true
# Create workspace configuration
cat > .space/workspace.kts << 'EOF'
workspace {
services = listOf(
"services/user-service",
"services/order-service"
)
libraries = listOf(
"libs/shared"
)
// Shared build configuration
gradle {
version = "7.6"
distributionType = "ALL"
}
}
EOF
Mastering Code Reviews in Space
Advanced Code Review Configuration
// .space/code-review-advanced.kts
codeReview {
// Custom review workflows
workflow("feature-review") {
triggers {
pullRequest {
targetBranch = "develop"
sourceBranchPattern = "feature/*"
}
}
stages {
stage("automated-checks") {
parallel {
job("code-quality") {
container("gradle:7.6-jdk11") {
shellScript {
content = """
./gradlew detekt spotlessCheck
./gradlew jacocoTestReport
echo "Code quality checks passed"
"""
}
}
}
job("security-scan") {
container("owasp/dependency-check:latest") {
shellScript {
content = """
dependency-check.sh --project "MyApp" --scan .
echo "Security scan completed"
"""
}
}
}
}
}
stage("human-review") {
requiresApproval {
reviewers = listOf("senior-developers")
minApprovals = 2
}
}
}
}
// Review automation rules
automation {
// Auto-approve dependency updates
rule("auto-approve-deps") {
condition = pullRequestTitle.contains("[deps]") &&
changedFiles.all { it.startsWith("gradle/") || it.endsWith(".gradle.kts") }
action = autoApprove()
}
// Auto-assign reviewers based on complexity
rule("assign-senior-for-complex") {
condition = changedLinesCount > 500 || changedFilesCount > 20
action = assignReviewers("senior-developers", "architects")
}
}
}
Code Review Templates
// .space/review-templates.kts
reviewTemplate("api-review") {
title = "π API Review Checklist"
checklist = listOf(
"Are new endpoints properly documented?",
"Do API responses follow the standard format?",
"Are proper HTTP status codes used?",
"Is input validation implemented?",
"Are rate limiting considerations addressed?",
"Is backward compatibility maintained?",
"Are security headers included?",
"Is the API versioned correctly?"
)
requiredReviewers = listOf("api-team", "security-team")
}
reviewTemplate("database-review") {
title = "ποΈ Database Review Checklist"
checklist = listOf(
"Are migrations backward compatible?",
"Are indexes properly defined?",
"Is data integrity maintained?",
"Are foreign keys correctly defined?",
"Is the migration tested on staging?",
"Are performance implications considered?",
"Is rollback strategy documented?"
)
requiredReviewers = listOf("database-team", "backend-team")
}
Space Automation: CI/CD with Kotlin DSL
Complete CI/CD Pipeline Example
// .space/automation.kts - Production-ready pipeline
job("Full CI/CD Pipeline") {
startOn {
gitPush {
branchFilter {
+"main"
+"develop"
+"release/*"
}
}
}
// Environment variables
env["GRADLE_OPTS"] = "-Dorg.gradle.daemon=false -Dorg.gradle.caching=true"
env["JAVA_TOOL_OPTIONS"] = "-Xmx2g"
// Parallel execution for speed
parallel {
// Build and test
job("build-and-test") {
container("gradle:7.6-jdk17") {
cache {
location = "/root/.gradle"
key = "gradle-{{ hashFiles('**/*.gradle.kts', 'gradle.properties') }}"
}
shellScript {
content = """
set -e
echo "π¨ Building application..."
./gradlew clean build --parallel --build-cache
echo "π§ͺ Running tests..."
./gradlew test integrationTest --parallel
echo "π Generating reports..."
./gradlew jacocoTestReport
./gradlew sonarqube -Dsonar.token=${'$'}SONAR_TOKEN
"""
}
// Publish test results
kotlinScript { api ->
api.space().projects.automation.jobs.reports.publishTestReports(
job = api.executionContext().job(),
testReportDir = "build/test-results"
)
}
}
}
// Security scanning
job("security-scan") {
container("securecodewarrior/docker-clair:latest") {
shellScript {
content = """
echo "π Running security scans..."
# OWASP Dependency Check
dependency-check.sh --project "MyApp" --scan . --format XML
# License compliance check
license-checker --onlyAllow 'MIT;Apache-2.0;BSD-3-Clause'
echo "Security scans completed"
"""
}
}
}
// Code quality analysis
job("code-quality") {
container("gradle:7.6-jdk17") {
shellScript {
content = """
echo "π Running code quality checks..."
# Kotlin linting
./gradlew detekt
# Code formatting check
./gradlew spotlessCheck
# Architecture tests
./gradlew archUnit
echo "Code quality checks passed"
"""
}
}
}
}
// Conditional deployment
job("deploy") {
startOn {
jobCompleted {
job = "build-and-test"
result = TaskResult.SUCCESSFUL
}
jobCompleted {
job = "security-scan"
result = TaskResult.SUCCESSFUL
}
}
container("alpine/k8s:1.24.0") {
env["KUBECONFIG"] = Secrets("kubeconfig-prod")
env["REGISTRY_TOKEN"] = Secrets("docker-registry-token")
shellScript {
content = """
set -e
# Determine deployment environment
if [ "${'$'}JB_SPACE_GIT_BRANCH" = "main" ]; then
ENVIRONMENT="production"
NAMESPACE="myapp-prod"
elif [ "${'$'}JB_SPACE_GIT_BRANCH" = "develop" ]; then
ENVIRONMENT="staging"
NAMESPACE="myapp-staging"
else
echo "Branch ${'$'}JB_SPACE_GIT_BRANCH not configured for deployment"
exit 0
fi
echo "π Deploying to ${'$'}ENVIRONMENT..."
# Build and push Docker image
docker build -t myapp:${'$'}JB_SPACE_GIT_REVISION .
docker tag myapp:${'$'}JB_SPACE_GIT_REVISION registry.company.com/myapp:${'$'}JB_SPACE_GIT_REVISION
docker push registry.company.com/myapp:${'$'}JB_SPACE_GIT_REVISION
# Deploy to Kubernetes
helm upgrade --install myapp ./helm \
--namespace ${'$'}NAMESPACE \
--set image.tag=${'$'}JB_SPACE_GIT_REVISION \
--set environment=${'$'}ENVIRONMENT \
--wait --timeout=10m
echo "β
Deployment to ${'$'}ENVIRONMENT completed"
"""
}
}
}
}
Advanced Pipeline Features
// .space/advanced-pipelines.kts
job("Multi-Stage Deployment") {
// Matrix builds for different platforms
matrix {
axes["os"] = listOf("ubuntu-latest", "windows-latest", "macos-latest")
axes["java"] = listOf("11", "17", "21")
}
container("gradle:7.6-jdk${'$'}{{ matrix.java }}") {
shellScript {
content = """
echo "Building on ${'$'}{{ matrix.os }} with Java ${'$'}{{ matrix.java }}"
./gradlew build -PjavaVersion=${'$'}{{ matrix.java }}
"""
}
}
}
// Blue-green deployment pipeline
job("blue-green-deployment") {
parameters {
text("TARGET_ENV", defaultValue = "staging")
choice("DEPLOYMENT_STRATEGY", options = listOf("blue-green", "rolling", "canary"))
boolean("SKIP_TESTS", defaultValue = false)
}
container("alpine/k8s:1.24.0") {
shellScript {
content = """
set -e
TARGET_ENV=${'$'}{{ run.TARGET_ENV }}
STRATEGY=${'$'}{{ run.DEPLOYMENT_STRATEGY }}
if [ "${'$'}STRATEGY" = "blue-green" ]; then
echo "π Executing blue-green deployment to ${'$'}TARGET_ENV"
# Get current active color
CURRENT_COLOR=$(kubectl get service myapp-service -n myapp-${'$'}TARGET_ENV -o jsonpath='{.spec.selector.color}')
NEW_COLOR=$([ "${'$'}CURRENT_COLOR" = "blue" ] && echo "green" || echo "blue")
echo "Current: ${'$'}CURRENT_COLOR, Deploying: ${'$'}NEW_COLOR"
# Deploy to new color
helm upgrade --install myapp-${'$'}NEW_COLOR ./helm \
--namespace myapp-${'$'}TARGET_ENV \
--set color=${'$'}NEW_COLOR \
--set image.tag=${'$'}JB_SPACE_GIT_REVISION
# Wait for deployment to be ready
kubectl wait --for=condition=available deployment/myapp-${'$'}NEW_COLOR \
-n myapp-${'$'}TARGET_ENV --timeout=600s
# Switch traffic
kubectl patch service myapp-service \
-n myapp-${'$'}TARGET_ENV \
-p '{"spec":{"selector":{"color":"'${'$'}NEW_COLOR'"}}}'
echo "β
Blue-green deployment completed"
fi
"""
}
}
}
Package Management & Registries
Setting Up Private Package Registries
// .space/packages.kts
packageRepository {
maven {
name = "company-releases"
url = "https://maven.jetbrains.space/company/p/platform/maven"
authentication {
username = Params("maven.username")
password = Secrets("maven.password")
}
// Publication settings
publications {
publication("main") {
groupId = "com.company.platform"
artifactId = "core-library"
version = env("VERSION") ?: "1.0-SNAPSHOT"
}
}
}
npm {
name = "company-npm"
url = "https://npm.jetbrains.space/company/p/platform/npm"
scopes = listOf("@company")
authentication {
token = Secrets("npm.token")
}
}
docker {
name = "company-docker"
url = "registry.jetbrains.space/company/p/platform/docker"
authentication {
username = Params("docker.username")
password = Secrets("docker.password")
}
}
}
Gradle Integration with Space Packages
// build.gradle.kts
plugins {
kotlin("jvm")
`maven-publish`
id("com.jetbrains.space.maven") version "1.0"
}
repositories {
mavenCentral()
// Space Maven repository
maven {
name = "SpacePackages"
url = uri("https://maven.jetbrains.space/company/p/platform/maven")
credentials {
username = project.findProperty("space.maven.username") as String?
password = project.findProperty("space.maven.password") as String?
}
}
}
dependencies {
// Internal company libraries
implementation("com.company.platform:core-library:2.1.0")
implementation("com.company.platform:security-utils:1.5.0")
// External dependencies
implementation("org.springframework.boot:spring-boot-starter:2.7.0")
implementation("org.jetbrains.kotlin:kotlin-stdlib")
}
publishing {
publications {
create<MavenPublication>("maven") {
from(components["java"])
groupId = "com.company.platform"
artifactId = "my-service"
version = System.getenv("VERSION") ?: "1.0-SNAPSHOT"
pom {
name.set("My Service")
description.set("Core business logic service")
developers {
developer {
id.set("team-backend")
name.set("Backend Team")
email.set("[email protected]")
}
}
}
}
}
repositories {
maven {
name = "SpacePackages"
url = uri("https://maven.jetbrains.space/company/p/platform/maven")
credentials {
username = System.getenv("SPACE_MAVEN_USERNAME")
password = System.getenv("SPACE_MAVEN_PASSWORD")
}
}
}
}
Team Collaboration Features
Advanced Chat and Communication Setup
// .space/collaboration.kts
team {
channels {
channel("general") {
description = "General team discussions"
type = ChannelType.PUBLIC
integrations {
// Git notifications
gitIntegration {
events = listOf(
GitEvent.PUSH,
GitEvent.MERGE_REQUEST_CREATED,
GitEvent.MERGE_REQUEST_MERGED
)
branches = listOf("main", "develop")
}
// Build notifications
buildIntegration {
events = listOf(
BuildEvent.FAILED,
BuildEvent.SUCCESS_AFTER_FAILURE
)
jobs = listOf("deployment", "integration-tests")
}
}
}
channel("alerts") {
description = "System alerts and monitoring"
type = ChannelType.PUBLIC
integrations {
// Custom webhook for external monitoring
webhook {
url = "https://monitoring.company.com/webhook/space"
events = listOf("deployment", "incident")
}
}
}
channel("backend-team") {
description = "Backend team private discussions"
type = ChannelType.PRIVATE
members = listOf("@backend-developers", "@tech-leads")
}
}
// Meeting rooms and calendars
meetings {
recurringMeeting("weekly-standup") {
title = "Weekly Team Standup"
schedule = CronSchedule("0 9 * * MON") // Every Monday at 9 AM
duration = Duration.minutes(30)
participants = listOf("@development-team")
agenda = """
- What did you accomplish last week?
- What are you working on this week?
- Any blockers or concerns?
- Review sprint progress
""".trimIndent()
}
recurringMeeting("architecture-review") {
title = "Architecture Review Meeting"
schedule = CronSchedule("0 14 * * FRI") // Every Friday at 2 PM
duration = Duration.hours(1)
participants = listOf("@architects", "@senior-developers")
}
}
}
Knowledge Base and Documentation
// .space/knowledge-base.kts
knowledgeBase {
// Technical documentation
folder("technical-docs") {
article("api-guidelines") {
title = "API Development Guidelines"
content = """
# API Development Guidelines
## REST API Standards
### URL Structure
```
GET /api/v1/users # List users
GET /api/v1/users/{id} # Get specific user
POST /api/v1/users # Create user
PUT /api/v1/users/{id} # Update user
DELETE /api/v1/users/{id} # Delete user
```
### Response Format
```json
{
"data": { ... },
"meta": {
"timestamp": "2025-01-15T10:30:00Z",
"version": "1.0"
}
}
```
### Error Handling
```json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input data",
"details": [
{
"field": "email",
"message": "Must be a valid email address"
}
]
}
}
```
""".trimIndent()
tags = listOf("api", "standards", "backend")
authors = listOf("@api-team")
}
article("deployment-guide") {
title = "Production Deployment Guide"
content = """
# Production Deployment Guide
## Pre-deployment Checklist
- [ ] All tests passing
- [ ] Security scan completed
- [ ] Database migrations tested
- [ ] Rollback plan prepared
- [ ] Monitoring alerts configured
## Deployment Process
### 1. Prepare Release
```bash
git checkout main
git pull origin main
git tag v1.2.3
git push origin v1.2.3
```
### 2. Build and Test
```bash
./gradlew clean build
docker build -t myapp:v1.2.3 .
docker run --rm myapp:v1.2.3 ./gradlew test
```
### 3. Deploy to Staging
```bash
helm upgrade myapp-staging ./helm/myapp \
--set image.tag=v1.2.3 \
--set environment=staging
```
### 4. Smoke Tests
```bash
curl https://staging.company.com/health
./scripts/integration-tests.sh staging
```
### 5. Production Deployment
```bash
helm upgrade myapp-prod ./helm/myapp \
--set image.tag=v1.2.3 \
--set environment=production \
--wait
```
""".trimIndent()
tags = listOf("deployment", "devops", "production")
authors = listOf("@devops-team")
}
}
// Process documentation
folder("processes") {
article("code-review-process") {
title = "Code Review Process"
content = """
# Code Review Process
## When to Create a Merge Request
- Feature is complete and tested locally
- All acceptance criteria are met
- Code follows team conventions
- Documentation is updated
## Review Checklist
### Functionality
- [ ] Code does what it's supposed to do
- [ ] Edge cases are handled
- [ ] Error handling is appropriate
### Code Quality
- [ ] Code is readable and maintainable
- [ ] Functions/methods are focused and small
- [ ] No code duplication
- [ ] Consistent naming conventions
### Testing
- [ ] Adequate test coverage
- [ ] Tests are meaningful and not just for coverage
- [ ] Integration tests for new features
### Security
- [ ] No sensitive data in code
- [ ] Input validation implemented
- [ ] Authentication/authorization checked
""".trimIndent()
tags = listOf("process", "code-review", "quality")
}
}
}
IDE Integration Mastery
Complete IntelliJ IDEA Setup
// .idea/space.xml - IDE configuration for Space
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SpaceSettings">
<option name="serverUrl" value="https://company.jetbrains.space" />
<option name="organizationName" value="company" />
<option name="enableAutomaticUpdates" value="true" />
<option name="showCodeReviewNotifications" value="true" />
<option name="showBuildNotifications" value="true" />
<option name="autoSyncIssues" value="true" />
</component>
<component name="SpaceCodeReview">
<option name="enableInlineComments" value="true" />
<option name="enableSuggestions" value="true" />
<option name="autoRefreshReviews" value="5000" />
</component>
</project>
Advanced IDE Integration Features
// .space/ide-integration.kts
ideIntegration {
// Custom IDE actions
actions {
action("quick-deploy-staging") {
name = "Quick Deploy to Staging"
description = "Deploy current branch to staging environment"
shortcut = "Ctrl+Alt+D"
script = """
git push origin HEAD
curl -X POST https://company.jetbrains.space/api/automation/trigger \
-H "Authorization: Bearer ${'}SPACE_TOKEN" \
-d '{"job": "deploy-staging", "branch": "'$(git branch --show-current)'"}'
"""
}
action("create-hotfix") {
name = "Create Hotfix Branch"
description = "Create and checkout hotfix branch from main"
shortcut = "Ctrl+Alt+H"
script = """
git checkout main
git pull origin main
HOTFIX_NAME="hotfix/$(date +%Y%m%d-%H%M)-$(whoami)"
git checkout -b ${'}HOTFIX_NAME
echo "Created hotfix branch: ${'}HOTFIX_NAME"
"""
}
}
// Live templates for common patterns
liveTemplates {
template("space-job") {
abbreviation = "spacejob"
description = "Space automation job template"
text = """
job("${'}JOB_NAME${'}") {
startOn {
${'}TRIGGER${'}
}
container("${'}IMAGE${'}") {
shellScript {
content = ${'}"""
${'}SCRIPT${'}
${'}""".trimIndent()
}
}
}
"""
variables {
variable("JOB_NAME") {
defaultValue = "my-job"
}
variable("TRIGGER") {
defaultValue = "gitPush()"
}
variable("IMAGE") {
defaultValue = "gradle:7.6-jdk17"
}
variable("SCRIPT") {
defaultValue = "echo \"Hello Space!\""
}
}
}
template("space-review") {
abbreviation = "spacereview"
description = "Space code review template"
text = """
## Summary
${'}SUMMARY${'}
## Changes Made
- ${'}CHANGE1${'}
- ${'}CHANGE2${'}
## Testing
${'}TESTING${'}
## Checklist
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] Backward compatibility maintained
- [ ] Security considerations reviewed
"""
}
}
}
Debugging Space Automation from IDE
// .space/debug-automation.kts
job("Debug Pipeline") {
startOn {
// Trigger manually for debugging
schedule { cron("0 0 * * *") } // Daily at midnight, disabled by default
}
// Enable debugging features
env["DEBUG"] = "true"
env["SPACE_AUTOMATION_DEBUG"] = "true"
container("gradle:7.6-jdk17") {
// Enable remote debugging
env["JAVA_TOOL_OPTIONS"] = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
shellScript {
content = """
set -x # Enable verbose output
echo "π Debug mode enabled"
echo "Environment variables:"
printenv | sort
echo "π Analyzing project structure..."
find . -name "*.gradle.kts" -o -name "*.kt" | head -20
echo "π§ͺ Running debug build..."
./gradlew build --debug --stacktrace
# Wait for debugger attachment if needed
if [ "${'}WAIT_FOR_DEBUGGER" = "true" ]; then
echo "β±οΈ Waiting for debugger attachment on port 5005..."
sleep 300 # Wait 5 minutes
fi
echo "β
Debug pipeline completed"
"""
}
}
}
Advanced Workflows & Best Practices
GitFlow Integration with Space
// .space/gitflow.kts
gitflow {
// Branch naming conventions
branches {
main = "main"
develop = "develop"
feature = "feature/"
release = "release/"
hotfix = "hotfix/"
}
// Automated workflows for each branch type
workflows {
// Feature branch workflow
workflow("feature-workflow") {
trigger {
branchPattern = "feature/*"
events = listOf(GitEvent.PUSH, GitEvent.MERGE_REQUEST_CREATED)
}
jobs {
job("feature-validation") {
container("gradle:7.6-jdk17") {
shellScript {
content = """
echo "π Validating feature branch..."
# Run fast feedback loop
./gradlew compileKotlin compileTestKotlin
./gradlew detekt spotlessCheck
./gradlew test --tests="*Unit*"
# Feature-specific validations
FEATURE_NAME=$(echo ${'}JB_SPACE_GIT_BRANCH | sed 's/feature\///')
echo "Feature: ${'}FEATURE_NAME"
# Check for feature flag usage
if grep -r "FeatureFlag" src/; then
echo "β
Feature flags detected - good practice!"
fi
echo "β
Feature validation completed"
"""
}
}
}
}
}
// Release workflow
workflow("release-workflow") {
trigger {
branchPattern = "release/*"
events = listOf(GitEvent.PUSH)
}
jobs {
job("release-preparation") {
container("gradle:7.6-jdk17") {
shellScript {
content = """
echo "π Preparing release..."
# Extract version from branch name
VERSION=$(echo ${'}JB_SPACE_GIT_BRANCH | sed 's/release\///')
echo "Release version: ${'}VERSION"
# Update version in build files
sed -i "s/version = .*/version = \"${'}VERSION\"/" build.gradle.kts
# Generate changelog
./scripts/generate-changelog.sh ${'}VERSION
# Run comprehensive tests
./gradlew clean build integrationTest
# Security and compliance checks
./gradlew dependencyCheckAnalyze
echo "β
Release preparation completed"
"""
}
}
}
job("release-validation") {
container("alpine/k8s:1.24.0") {
shellScript {
content = """
echo "π§ͺ Validating release deployment..."
VERSION=$(echo ${'}JB_SPACE_GIT_BRANCH | sed 's/release\///')
# Deploy to staging
helm upgrade --install myapp-staging ./helm \
--set image.tag=${'}VERSION \
--set environment=staging \
--namespace myapp-staging
# Run acceptance tests
./scripts/acceptance-tests.sh staging
# Performance testing
./scripts/performance-tests.sh staging
echo "β
Release validation completed"
"""
}
}
}
}
}
}
}
Multi-Environment Deployment Strategy
// .space/environments.kts
environments {
environment("development") {
description = "Development environment for feature testing"
deployment {
strategy = DeploymentStrategy.DIRECT
autoDeployBranches = listOf("develop", "feature/*")
kubernetes {
namespace = "myapp-dev"
context = "dev-cluster"
resources {
requests {
cpu = "100m"
memory = "256Mi"
}
limits {
cpu = "500m"
memory = "512Mi"
}
}
}
configuration {
env("DATABASE_URL") { value = "postgresql://dev-db:5432/myapp" }
env("REDIS_URL") { value = "redis://dev-redis:6379" }
env("LOG_LEVEL") { value = "DEBUG" }
env("FEATURE_FLAGS_ENABLED") { value = "true" }
}
}
}
environment("staging") {
description = "Staging environment for integration testing"
deployment {
strategy = DeploymentStrategy.BLUE_GREEN
requiresApproval = false
autoDeployBranches = listOf("develop", "release/*")
kubernetes {
namespace = "myapp-staging"
context = "staging-cluster"
resources {
requests {
cpu = "200m"
memory = "512Mi"
}
limits {
cpu = "1000m"
memory = "1Gi"
}
}
}
healthChecks {
httpGet {
path = "/health"
port = 8080
initialDelaySeconds = 30
periodSeconds = 10
}
}
configuration {
env("DATABASE_URL") { secret = "staging-db-url" }
env("REDIS_URL") { secret = "staging-redis-url" }
env("LOG_LEVEL") { value = "INFO" }
env("MONITORING_ENABLED") { value = "true" }
}
}
}
environment("production") {
description = "Production environment"
deployment {
strategy = DeploymentStrategy.CANARY
requiresApproval = true
approvers = listOf("@devops-team", "@tech-leads")
autoDeployBranches = listOf("main")
kubernetes {
namespace = "myapp-prod"
context = "prod-cluster"
resources {
requests {
cpu = "500m"
memory = "1Gi"
}
limits {
cpu = "2000m"
memory = "2Gi"
}
}
replicas = 3
affinity {
podAntiAffinity {
requiredDuringSchedulingIgnoredDuringExecution {
topologyKey = "kubernetes.io/hostname"
}
}
}
}
canaryDeployment {
initialWeight = 10
incrementWeight = 10
maxWeight = 100
analysisInterval = Duration.minutes(5)
metrics {
metric("error-rate") {
query = "sum(rate(http_requests_total{status=~'5..'}[5m])) / sum(rate(http_requests_total[5m]))"
threshold = 0.01 // 1% error rate
}
metric("response-time") {
query = "histogram_quantile(0.95, http_request_duration_seconds_bucket)"
threshold = 0.5 // 500ms p95 response time
}
}
}
configuration {
env("DATABASE_URL") { secret = "prod-db-url" }
env("REDIS_URL") { secret = "prod-redis-url" }
env("LOG_LEVEL") { value = "WARN" }
env("MONITORING_ENABLED") { value = "true" }
env("METRICS_ENABLED") { value = "true" }
}
}
}
}
Migration Strategies
Migrating from GitHub to Space
#!/bin/bash
# migration-to-space.sh - Complete migration script
set -e
echo "π Starting migration from GitHub to JetBrains Space..."
# Configuration
GITHUB_ORG="your-github-org"
SPACE_ORG="your-space-org"
GITHUB_TOKEN="your-github-token"
SPACE_TOKEN="your-space-token"
# Create migration directory
mkdir -p migration-workspace
cd migration-workspace
# Step 1: Export GitHub repositories
echo "π¦ Exporting GitHub repositories..."
gh api "/orgs/$GITHUB_ORG/repos" --paginate > github-repos.json
# Process each repository
jq -r '.[].clone_url' github-repos.json | while read -r repo_url; do
repo_name=$(basename "$repo_url" .git)
echo "Cloning $repo_name..."
# Clone with full history
git clone --mirror "$repo_url" "$repo_name.git"
# Export issues and PRs
gh api "/repos/$GITHUB_ORG/$repo_name/issues" --paginate > "$repo_name-issues.json"
gh api "/repos/$GITHUB_ORG/$repo_name/pulls" --paginate > "$repo_name-prs.json"
echo "β
Exported $repo_name"
done
# Step 2: Create Space repositories
echo "ποΈ Creating Space repositories..."
jq -r '.[] | "\(.name) \(.description // "")"' github-repos.json | while read -r name description; do
echo "Creating Space repository: $name"
curl -X POST "https://$SPACE_ORG.jetbrains.space/api/http/projects/key:main/repositories" \
-H "Authorization: Bearer $SPACE_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\":\"$name\",\"description\":\"$description\"}"
done
Step 3: Push repositories to Space
jq -r '.[].name' github-repos.json | while read -r repo_name; do
echo "Pushing $repo_name to Space..."
cd "$repo_name.git"
git remote add space "https://git.jetbrains.space/$SPACE_ORG/main/$repo_name.git"
git push --mirror space
cd ..
echo "β
Migrated $repo_name"
done
Step 4: Migrate GitHub Actions to Space Automation
echo "π Converting GitHub Actions to Space Automation..."
find . -name "*.yml" -path "*/.github/workflows/*" | while read -r workflow_file; do
repo_dir=$(dirname $(dirname $(dirname "$workflow_file")))
repo_name=$(basename "$repo_dir" .git)
echo "Converting workflow: $workflow_file"
# Create Space automation file
cat > "$repo_name-automation.kts" << 'EOF'
// Converted from GitHub Actions
job("migrated-workflow") {
startOn {
gitPush {
branchFilter {
+"main"
+"develop"
}
}
}
container("gradle:7.6-jdk17") {
shellScript {
content = """
# Converted GitHub Actions steps
echo "Running migrated workflow..."
# Add your converted steps here
./gradlew clean build test
"""
}
}
}
EOF
echo "β
Created automation for $repo_name"
done
echo "π Migration completed! Please review and customize the generated automation files."
Migrating from GitLab to Space
# .gitlab-ci-to-space.yml - GitLab CI conversion reference
stages:
- build
- test
- deploy
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
build:
stage: build
script:
- ./gradlew clean build
artifacts:
paths:
- build/
test:
stage: test
script:
- ./gradlew test
coverage: '/Total.*?([0-9]{1,3})%/'
deploy:
stage: deploy
script:
- kubectl apply -f k8s/
only:
- main
// Equivalent Space automation
job("GitLab Migration") {
startOn {
gitPush {
branchFilter {
+"main"
+"develop"
}
}
}
// Build stage
parallel {
job("build") {
container("gradle:7.6-jdk17") {
env["GRADLE_OPTS"] = "-Dorg.gradle.daemon=false"
shellScript {
content = """
./gradlew clean build
"""
}
// Store artifacts
fileArtifacts {
localPath = "build/"
remotePath = "build-artifacts"
}
}
}
job("test") {
container("gradle:7.6-jdk17") {
shellScript {
content = """
./gradlew test
./gradlew jacocoTestReport
"""
}
// Publish test results
kotlinScript { api ->
api.space().projects.automation.jobs.reports.publishTestReports(
job = api.executionContext().job(),
testReportDir = "build/test-results"
)
}
}
}
}
// Deploy stage (only for main branch)
job("deploy") {
startOn {
jobCompleted {
job = "build"
result = TaskResult.SUCCESSFUL
}
}
condition {
gitBranch { equals("main") }
}
container("alpine/k8s:1.24.0") {
shellScript {
content = """
kubectl apply -f k8s/
"""
}
}
}
}
GitHub vs. JetBrains Space
Detailed Feature Comparison
Feature Category | GitHub | JetBrains Space | Winner |
---|---|---|---|
Repository Hosting | β Excellent | β Excellent | Tie |
IDE Integration | β οΈ Good (via extensions) | β Native & Deep | Space |
CI/CD | β GitHub Actions (YAML) | β Kotlin DSL | Space |
Code Review | β Pull Requests | β Merge Requests + IDE | Space |
Issue Tracking | β Issues + Projects | β Issues + Boards | Tie |
Package Registry | β GitHub Packages | β Space Packages | Tie |
Team Chat | β No native chat | β Integrated Chat | Space |
Knowledge Base | β οΈ Wiki only | β Full KB + Blogs | Space |
Open Source | β Massive ecosystem | β Limited | GitHub |
Community | β Huge community | β Smaller | GitHub |
Pricing | β Free tier generous | β οΈ More expensive | GitHub |
Learning Curve | β Gentle | β οΈ Steeper | GitHub |
Migration Decision Matrix
// decision-matrix.kts - Framework for choosing between platforms
data class PlatformRequirement(
val name: String,
val importance: Int, // 1-10
val githubScore: Int, // 1-10
val spaceScore: Int // 1-10
)
val requirements = listOf(
PlatformRequirement("IDE Integration", 9, 6, 10),
PlatformRequirement("Open Source Support", 8, 10, 3),
PlatformRequirement("Team Collaboration", 7, 5, 9),
PlatformRequirement("CI/CD Flexibility", 8, 7, 9),
PlatformRequirement("Learning Curve", 6, 9, 6),
PlatformRequirement("Cost Effectiveness", 7, 8, 6),
PlatformRequirement("Ecosystem Maturity", 8, 9, 6),
PlatformRequirement("Unified Workflow", 9, 4, 10)
)
fun calculateScore(requirements: List<PlatformRequirement>, isGitHub: Boolean): Double {
return requirements.sumOf { req ->
val score = if (isGitHub) req.githubScore else req.spaceScore
req.importance * score
}.toDouble() / requirements.sumOf { it.importance * 10 }
}
// Usage:
// GitHub Score: calculateScore(requirements, true)
// Space Score: calculateScore(requirements, false)
When to Choose Each Platform
Choose GitHub when:
- Building open-source projects
- Need massive community support
- Cost is a primary concern
- Team is distributed and not using JetBrains IDEs
- Require extensive third-party integrations
Choose JetBrains Space when:
- Team heavily uses JetBrains IDEs
- Need unified development environment
- Want type-safe CI/CD configuration
- Require integrated team collaboration
- Building private/commercial products
Troubleshooting Common Issues
Space Automation Debugging
// .space/troubleshooting.kts
job("Debug Common Issues") {
container("alpine:latest") {
shellScript {
content = """
set -e
echo "π§ Space Troubleshooting Guide"
echo "=============================="
# Issue 1: Authentication problems
echo "1. Checking authentication..."
if [ -z "$SPACE_TOKEN" ]; then
echo "β SPACE_TOKEN not set"
echo " Solution: Add SPACE_TOKEN to your secrets"
else
echo "β
SPACE_TOKEN is configured"
fi
# Issue 2: Git authentication
echo "2. Testing Git access..."
git ls-remote https://git.jetbrains.space/company/project/repo.git || {
echo "β Git access failed"
echo " Solutions:"
echo " - Check repository permissions"
echo " - Verify authentication token"
echo " - Confirm repository URL"
}
# Issue 3: Container registry issues
echo "3. Testing container registry..."
docker pull registry.jetbrains.space/company/project/image:latest || {
echo "β Container registry access failed"
echo " Solutions:"
echo " - Check registry permissions"
echo " - Verify docker credentials"
echo " - Confirm image exists"
}
# Issue 4: Build cache problems
echo "4. Checking build cache..."
if [ -d "/root/.gradle/caches" ]; then
echo "β
Gradle cache directory exists"
ls -la /root/.gradle/caches/ | head -5
else
echo "β οΈ Gradle cache not found"
echo " This may slow down builds"
fi
# Issue 5: Environment variable issues
echo "5. Environment variables:"
printenv | grep -E "(SPACE_|JB_)" | sort
echo "π Troubleshooting completed"
"""
}
}
}
Common Configuration Fixes
// .space/fixes.kts
job("Apply Common Fixes") {
container("gradle:7.6-jdk17") {
shellScript {
content = """
# Fix 1: Gradle daemon issues
echo "Applying Gradle fixes..."
export GRADLE_OPTS="-Dorg.gradle.daemon=false -Xmx2g"
# Fix 2: Docker layer caching
echo "Optimizing Docker builds..."
cat > Dockerfile.optimized << 'EOF'
FROM gradle:7.6-jdk17 as builder
COPY build.gradle.kts settings.gradle.kts ./
COPY gradle gradle
RUN gradle dependencies --no-daemon
COPY src src
RUN gradle build --no-daemon
FROM openjdk:17-jre-slim
COPY --from=builder /home/gradle/build/libs/*.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
EOF
# Fix 3: Memory optimization
echo "Setting JVM memory limits..."
export JAVA_TOOL_OPTIONS="-XX:MaxRAMPercentage=75 -XX:+UseContainerSupport"
# Fix 4: Network timeout issues
echo "Configuring network timeouts..."
git config --global http.postBuffer 524288000
git config --global http.timeout 300
echo "β
Fixes applied successfully"
"""
}
}
}
Performance Optimization
Build Performance Optimization
// .space/performance.kts
job("Optimized Build") {
startOn {
gitPush()
}
container("gradle:7.6-jdk17") {
resources {
cpu = "2000m"
memory = "4Gi"
}
// Optimized caching strategy
cache {
location = "/root/.gradle"
key = "gradle-{{ hashFiles('**/*.gradle.kts', 'gradle.properties', 'gradle/wrapper/gradle-wrapper.properties') }}"
restoreKeys = listOf(
"gradle-{{ hashFiles('**/*.gradle.kts', 'gradle.properties') }}",
"gradle-"
)
}
cache {
location = "/root/.m2"
key = "maven-{{ hashFiles('**/pom.xml') }}"
}
env["GRADLE_OPTS"] = "-Dorg.gradle.daemon=false -Dorg.gradle.caching=true -Dorg.gradle.parallel=true"
env["JAVA_TOOL_OPTIONS"] = "-Xmx3g -XX:+UseContainerSupport -XX:MaxRAMPercentage=75"
shellScript {
content = """
set -e
echo "π Starting optimized build..."
# Pre-download dependencies
echo "π¦ Downloading dependencies..."
./gradlew dependencies --no-daemon --parallel
# Compile incrementally
echo "π¨ Compiling..."
./gradlew compileKotlin compileTestKotlin --no-daemon --parallel --build-cache
# Run tests in parallel
echo "π§ͺ Running tests..."
./gradlew test --no-daemon --parallel --continue
# Build final artifacts
echo "π¦ Building artifacts..."
./gradlew build --no-daemon --parallel --build-cache
# Performance metrics
echo "π Build performance metrics:"
echo "Build time: $(date)"
echo "Memory usage: $(free -h | grep Mem)"
echo "Disk usage: $(df -h /tmp)"
echo "β
Optimized build completed"
"""
}
}
}
Container Optimization
# Dockerfile.optimized - Multi-stage optimized build
# Stage 1: Build dependencies
FROM gradle:7.6-jdk17-alpine as dependencies
WORKDIR /app
COPY build.gradle.kts settings.gradle.kts gradle.properties ./
COPY gradle gradle
RUN gradle dependencies --no-daemon --quiet
# Stage 2: Build application
FROM gradle:7.6-jdk17-alpine as builder
WORKDIR /app
COPY --from=dependencies /home/gradle/.gradle /home/gradle/.gradle
COPY . .
RUN gradle build --no-daemon --build-cache -x test
# Stage 3: Run tests
FROM gradle:7.6-jdk17-alpine as tester
WORKDIR /app
COPY --from=dependencies /home/gradle/.gradle /home/gradle/.gradle
COPY . .
RUN gradle test --no-daemon --parallel
# Stage 4: Create runtime image
FROM openjdk:17-jre-alpine as runtime
RUN addgroup -g 1001 -S appuser && \
adduser -u 1001 -S appuser -G appuser
WORKDIR /app
COPY --from=builder --chown=appuser:appuser /app/build/libs/*.jar app.jar
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75", "-jar", "app.jar"]
Data Export and Migration
Comprehensive Data Export Script
#!/bin/bash
# space-data-export.sh - Export all Space data before migration
set -e
SPACE_ORG="your-org"
SPACE_TOKEN="your-token"
EXPORT_DIR="space-export-$(date +%Y%m%d-%H%M%S)"
API_BASE="https://$SPACE_ORG.jetbrains.space/api/http"
echo "π Starting comprehensive Space data export..."
mkdir -p "$EXPORT_DIR"
cd "$EXPORT_DIR"
# Export repositories
echo "π¦ Exporting repositories..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/projects/key:main/repositories" > repositories.json
# Clone all repositories
jq -r '.[].name' repositories.json | while read -r repo_name; do
echo "Cloning repository: $repo_name"
git clone --mirror "https://git.jetbrains.space/$SPACE_ORG/main/$repo_name.git" "$repo_name.git"
done
# Export issues
echo "π Exporting issues..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/projects/key:main/planning/issues" > issues.json
# Export merge requests
echo "π Exporting merge requests..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/projects/key:main/code-reviews" > merge-requests.json
# Export automation jobs
echo "βοΈ Exporting automation jobs..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/projects/key:main/automation/jobs" > automation-jobs.json
# Export team data
echo "π₯ Exporting team data..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/team-directory/profiles" > team-members.json
# Export chat channels
echo "π¬ Exporting chat data..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/chats/channels" > chat-channels.json
# Export packages
echo "π¦ Exporting package data..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/projects/key:main/packages" > packages.json
# Export blog posts and articles
echo "π Exporting knowledge base..."
curl -H "Authorization: Bearer $SPACE_TOKEN" \
"$API_BASE/blog/posts" > blog-posts.json
# Create export summary
echo "π Creating export summary..."
cat > export-summary.md << EOF
# Space Data Export Summary
**Export Date:** $(date)
**Organization:** $SPACE_ORG
**Export Directory:** $EXPORT_DIR
## Exported Data
### Repositories
- **Count:** $(jq length repositories.json)
- **Files:** repositories.json + individual .git directories
### Issues
- **Count:** $(jq length issues.json)
- **File:** issues.json
### Merge Requests
- **Count:** $(jq length merge-requests.json)
- **File:** merge-requests.json
### Automation Jobs
- **Count:** $(jq length automation-jobs.json)
- **File:** automation-jobs.json
### Team Members
- **Count:** $(jq length team-members.json)
- **File:** team-members.json
### Chat Channels
- **Count:** $(jq length chat-channels.json)
- **File:** chat-channels.json
### Packages
- **Count:** $(jq length packages.json)
- **File:** packages.json
### Blog Posts
- **Count:** $(jq length blog-posts.json)
- **File:** blog-posts.json
## Usage Instructions
1. **Repository Data:** Each repository is cloned as a bare repository (.git directory)
2. **Structured Data:** All other data is exported as JSON files
3. **Import to New Platform:** Use the conversion scripts provided in the migration guide
## Important Notes
β οΈ **Deprecation Notice:** JetBrains Space has been discontinued as of May 31, 2025
π
**Action Required:** Migrate to alternative platform before data becomes inaccessible
π **Security:** This export contains sensitive data - store securely
EOF
echo "β
Space data export completed successfully!"
echo "π Export location: $PWD"
echo "π Summary: export-summary.md"
Alternative Platform Migration
#!/bin/bash
# migrate-to-alternatives.sh - Migration options for Space users
echo "π JetBrains Space Migration Options"
echo "===================================="
# Option 1: Migrate to GitHub
migrate_to_github() {
echo "π Migrating to GitHub..."
# Create GitHub repositories
jq -r '.[] | "\(.name) \(.description // "")"' repositories.json | while read -r name description; do
gh repo create "your-org/$name" --description "$description" --private
# Push repository data
cd "$name.git"
git remote add github "https://github.com/your-org/$name.git"
git push --mirror github
cd ..
done
# Convert Space automation to GitHub Actions
cat > .github/workflows/migrated.yml << 'EOF'
name: Migrated from Space
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
run: ./gradlew build
EOF
echo "β
GitHub migration templates created"
}
# Option 2: Migrate to GitLab
migrate_to_gitlab() {
echo "π¦ Migrating to GitLab..."
# Create GitLab projects
jq -r '.[] | "\(.name) \(.description // "")"' repositories.json | while read -r name description; do
curl -X POST "https://gitlab.com/api/v4/projects" \
-H "Authorization: Bearer $GITLAB_TOKEN" \
-d "name=$name&description=$description&visibility=private"
# Push repository data
cd "$name.git"
git remote add gitlab "https://gitlab.com/your-group/$name.git"
git push --mirror gitlab
cd ..
done
# Convert to GitLab CI
cat > .gitlab-ci.yml << 'EOF'
# Migrated from JetBrains Space
stages:
- build
- test
- deploy
variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
build:
stage: build
image: gradle:7.6-jdk17
script:
- ./gradlew clean build
artifacts:
reports:
junit: build/test-results/test/TEST-*.xml
EOF
echo "β
GitLab migration templates created"
}
# Option 3: Migrate to Azure DevOps
migrate_to_azure_devops() {
echo "π· Migrating to Azure DevOps..."
# Create Azure DevOps pipeline
cat > azure-pipelines.yml << 'EOF'
# Migrated from JetBrains Space
trigger:
branches:
include:
- main
- develop
pool:
vmImage: 'ubuntu-latest'
variables:
GRADLE_OPTS: '-Dorg.gradle.daemon=false'
steps:
- task: JavaToolInstaller@0
inputs:
versionSpec: '17'
jdkArchitectureOption: 'x64'
jdkSourceOption: 'PreInstalled'
- script: |
./gradlew clean build
displayName: 'Build with Gradle'
- task: PublishTestResults@2
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/TEST-*.xml'
EOF
echo "β
Azure DevOps migration templates created"
}
# Interactive migration menu
echo "Choose your migration destination:"
echo "1) GitHub"
echo "2) GitLab"
echo "3) Azure DevOps"
echo "4) All platforms (generate all templates)"
read -p "Enter your choice (1-4): " choice
case $choice in
1) migrate_to_github ;;
2) migrate_to_gitlab ;;
3) migrate_to_azure_devops ;;
4)
migrate_to_github
migrate_to_gitlab
migrate_to_azure_devops
;;
*) echo "Invalid choice" ;;
esac
echo "π Migration preparation completed!"
Getting Started & Further Reading
Ready to experience a truly integrated development environment? Explore JetBrains Space with the official links.
Official Website: https://www.jetbrains.com/space/
Pricing Page: https://www.jetbrains.com/space/buy/
Documentation: https://www.jetbrains.com/help/space/
JetBrains Blog (for Space): https://blog.jetbrains.com/space/
FAQ
Q: Is JetBrains Space still available after the discontinuation announcement?
A: As of May 31, 2025, JetBrains has discontinued support and sales for Space and SpaceCode. Existing users may still have access to their instances, but no new subscriptions or updates are available.
Q: Can JetBrains Space be used without a JetBrains IDE?
A: Yes, Space can be used as a standalone platform via its web interface or mobile apps, but its true power lies in its deep integration with JetBrains IDEs like IntelliJ IDEA or PyCharm.
Q: How does Space compare to GitLab?
A: Space emphasizes IDE integration and a unified team environment, while GitLab focuses on a broader DevOps platform with strong open-source support. Spaceβs CI/CD uses Kotlin DSL, whereas GitLab uses YAML-based pipelines.
Q: Is Space suitable for open-source projects?
A: Space is primarily designed for private, professional teams and lacks the public-facing community features of platforms like GitHub or GitLab, making it less ideal for open-source projects.
Q: What happens to my data now that Space is discontinued?
A: JetBrains has provided guidance on data migration and exports in their official documentation. Check https://www.jetbrains.com/help/space/ for details on exporting repositories and other data.
Conclusion
JetBrains Space is a bold and compelling vision for the future of software development. It makes the case that the most productive teams are those whose tools meet them where they work: inside the IDE. By seamlessly blending top-tier DevOps features with essential team collaboration tools, Space offers a uniquely powerful and cohesive platform. For organizations already invested in the JetBrains ecosystem, itβs not just another alternative; itβs the ultimate upgrade.