Add releases

This commit is contained in:
2026-08-20 19:27:55 -04:00
parent 4b3bf1bfce
commit caed930d31
6 changed files with 327 additions and 80 deletions
+64
View File
@@ -0,0 +1,64 @@
name: Bug Report
about: Create a report to help us fix an issue with a3270
title: "[BUG] "
labels:
- bug
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to report an issue!
- type: input
id: host_environment
attributes:
label: Host Environment
description: What mainframe / operating system was connected (e.g., z/OS, z/VM, CMS, TSO, MVS 3.8j, Hercules/TK4-)?
placeholder: "e.g. z/VM 7.2 CMS, Hercules TK4-"
validations:
required: false
- type: input
id: android_device
attributes:
label: Android Device & OS Version
description: What Android device and Android version are you using?
placeholder: "e.g. Pixel 8, Android 14 (API 34)"
validations:
required: false
- type: dropdown
id: terminal_model
attributes:
label: Terminal Model
description: Terminal model in use
options:
- 3279-2 (Color 24x80)
- 3279-3 (Color 32x80)
- 3279-4 (Color 43x80)
- 3279-5 (Color 27x132)
- 3278 (Monochrome)
validations:
required: true
- type: textarea
id: description
attributes:
label: Problem Description
description: A clear and concise description of what went wrong.
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. Connect to host '...'
2. Open File Transfer dialog
3. Start IND$FILE GET ...
4. See error ...
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs / Logcat Output
description: Paste any logcat or debug logs here.
render: shell
@@ -0,0 +1,32 @@
name: Feature Request
about: Suggest an idea or enhancement for a3270
title: "[FEATURE] "
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
Thanks for suggesting a feature or enhancement for a3270!
- type: textarea
id: problem
attributes:
label: Is your feature request related to a problem?
description: A clear and concise description of what the problem or missing capability is.
placeholder: "I'm always frustrated when [...]"
validations:
required: false
- type: textarea
id: solution
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Describe alternatives you've considered
description: Any alternative solutions or features you've considered.
validations:
required: false
+61
View File
@@ -0,0 +1,61 @@
name: Build and Test a3270
on:
push:
branches: [ "main", "master", "develop" ]
pull_request:
branches: [ "main", "master" ]
workflow_dispatch:
jobs:
build:
name: Build Android APK
runs-on: ubuntu-latest
steps:
- name: Configure Dynamic DNS Resolvers
run: |
printf "nameserver 1.1.1.1\nnameserver 8.8.8.8\n" > /etc/resolv.conf 2>/dev/null || true
echo "64.22.43.251 git.hugfreevikings.wtf" | sudo tee -a /etc/hosts || echo "64.22.43.251 git.hugfreevikings.wtf" >> /etc/hosts || true
- name: Checkout Code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Checkout j3270 (for lib3270j)
run: |
git clone --depth 1 https://git.hugfreevikings.wtf/rudi/j3270.git j3270
- name: Set up Java JDK (Temurin 21)
uses: actions/setup-java@v3
continue-on-error: true
with:
java-version: '21'
distribution: 'temurin'
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Make scripts executable
run: |
chmod +x ./gradlew ./build.sh
- name: Build Android APK
run: |
./gradlew assembleDebug --no-daemon
env:
J3270_DIR: ${{ github.workspace }}/j3270
- name: Upload a3270 APK Artifact
uses: actions/upload-artifact@v3
continue-on-error: true
with:
name: a3270-debug
path: build/outputs/apk/debug/a3270-debug.apk
- name: Report Build Status
if: failure()
run: |
echo "### ❌ Build Failed" >> $GITHUB_STEP_SUMMARY
echo "Please check the runner logs above for details." >> $GITHUB_STEP_SUMMARY
-51
View File
@@ -1,51 +0,0 @@
name: Build a3270 APK
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
jobs:
build:
name: Build Android APK
runs-on: ubuntu-latest
steps:
- name: Configure DNS and Hosts
run: |
echo "64.22.43.251 git.hugfreevikings.wtf" | sudo tee -a /etc/hosts || echo "64.22.43.251 git.hugfreevikings.wtf" >> /etc/hosts || true
echo "nameserver 1.1.1.1" | sudo tee -a /etc/resolv.conf || echo "nameserver 1.1.1.1" >> /etc/resolv.conf || true
echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf || echo "nameserver 8.8.8.8" >> /etc/resolv.conf || true
- name: Checkout a3270
uses: actions/checkout@v4
- name: Checkout j3270 (for lib3270j)
run: |
git clone --depth 1 https://git.hugfreevikings.wtf/rudi/j3270.git j3270
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build Debug APK
run: ./gradlew assembleDebug --no-daemon
env:
J3270_DIR: ${{ github.workspace }}/j3270
- name: Upload APK Artifact
uses: actions/upload-artifact@v3
with:
name: a3270-debug
path: build/outputs/apk/debug/a3270-debug.apk
if-no-files-found: error
+88
View File
@@ -0,0 +1,88 @@
name: Release a3270
on:
push:
tags:
- 'v*'
jobs:
release:
name: Build & Publish Release
runs-on: ubuntu-latest
steps:
- name: Configure Dynamic DNS Resolvers
run: |
printf "nameserver 1.1.1.1\nnameserver 8.8.8.8\n" > /etc/resolv.conf 2>/dev/null || true
echo "64.22.43.251 git.hugfreevikings.wtf" | sudo tee -a /etc/hosts || echo "64.22.43.251 git.hugfreevikings.wtf" >> /etc/hosts || true
- name: Checkout Code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Checkout j3270 (for lib3270j)
run: |
git clone --depth 1 https://git.hugfreevikings.wtf/rudi/j3270.git j3270
- name: Set up Java JDK (Temurin 21)
uses: actions/setup-java@v3
continue-on-error: true
with:
java-version: '21'
distribution: 'temurin'
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Make scripts executable
run: |
chmod +x ./gradlew ./build.sh
- name: Build Android APK
run: |
./gradlew assembleDebug --no-daemon
env:
J3270_DIR: ${{ github.workspace }}/j3270
- name: Upload Release Artifact
uses: actions/upload-artifact@v3
continue-on-error: true
with:
name: a3270-${{ github.ref_name }}
path: build/outputs/apk/debug/a3270-debug.apk
- name: Publish Release to Gitea
continue-on-error: true
run: |
TAG="${{ github.ref_name }}"
API_URL="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases"
TOKEN="${{ secrets.GITHUB_TOKEN }}"
APK_FILE="build/outputs/apk/debug/a3270-debug.apk"
IS_PRERELEASE="false"
case "$TAG" in
*beta*|*alpha*|*rc*|*pre*|*preview*|*dev*)
IS_PRERELEASE="true"
echo "Tag $TAG detected as pre-release / beta."
;;
esac
echo "Creating Release for tag $TAG (prerelease=$IS_PRERELEASE)..."
RESPONSE=$(curl -s -X POST "$API_URL" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"tag_name\": \"$TAG\", \"name\": \"a3270 $TAG\", \"body\": \"Automated release for **$TAG**.\n\n### Installing a3270\n```bash\nadb install -r a3270.apk\n```\", \"draft\": false, \"prerelease\": $IS_PRERELEASE}")
RELEASE_ID=$(echo "$RESPONSE" | grep -o '"id":[0-9]*' | head -n 1 | cut -d':' -f2)
if [ -n "$RELEASE_ID" ] && [ -f "$APK_FILE" ]; then
echo "Uploading $APK_FILE to release $RELEASE_ID as a3270.apk..."
curl -s -X POST "$API_URL/$RELEASE_ID/assets?name=a3270.apk" \
-H "Authorization: token $TOKEN" \
-H "Content-Type: application/vnd.android.package-archive" \
--data-binary @"$APK_FILE"
echo "Release $TAG published with a3270.apk attached successfully!"
else
echo "Release API response: $RESPONSE"
fi
+82 -29
View File
@@ -1,33 +1,64 @@
# a3270 # a3270
An Android TN3270 terminal emulator based on `lib3270j` / `j3270`, built with Jetpack Compose and ported using AI. [![Build & Test](https://git.hugfreevikings.wtf/rudi/a3270/actions/workflows/build.yaml/badge.svg)](https://git.hugfreevikings.wtf/rudi/a3270/actions)
[![Latest Release](https://git.hugfreevikings.wtf/rudi/a3270/badges/release.svg)](https://git.hugfreevikings.wtf/rudi/a3270/releases)
[![Android](https://img.shields.io/badge/Android-API%2024%2B%20%7C%20Compose-green.svg)](https://developer.android.com)
[![License](https://img.shields.io/badge/License-MIT%20%2F%20BSD-green.svg)](LICENSE)
## Repositories An **x3270-aligned IBM 3270 mainframe terminal emulator for Android**, written in Kotlin using **Jetpack Compose** and powered by the `lib3270j` protocol engine from [j3270](https://git.hugfreevikings.wtf/rudi/j3270). Designed for mobile access to IBM z/OS, z/VM, CMS, and TSO systems over TN3270 and TN3270E.
---
## 🔗 Repositories
- **a3270 (Android App)**: https://git.hugfreevikings.wtf/rudi/a3270 - **a3270 (Android App)**: https://git.hugfreevikings.wtf/rudi/a3270
- **j3270 (Desktop App & `lib3270j` Core Library)**: https://git.hugfreevikings.wtf/rudi/j3270 - **j3270 (Desktop App & `lib3270j` Core Library)**: https://git.hugfreevikings.wtf/rudi/j3270
`a3270` relies on the shared 3270 protocol library (`lib3270j`) provided by the `j3270` repository. `a3270` relies on the shared 3270 protocol library (`lib3270j`) provided by the `j3270` repository.
## CI/CD & Automated Builds ---
Automated CI/CD is configured using Gitea Actions (`.gitea/workflows/build.yml`). On every push to `main` or pull request, the workflow automatically: ## 🚀 Quick Download & Install
1. Clones `a3270` and `j3270` (`lib3270j`).
2. Configures JDK 21 and the Android SDK.
3. Builds the debug APK (`a3270-debug.apk`).
4. Uploads the resulting APK as a downloadable workflow artifact (`a3270-debug`).
You can download pre-built APKs directly from the **Actions** tab of the repository on Gitea. ### Latest Standalone APK
You can download ready-to-install Android APKs directly from releases or CI builds:
## Prerequisites - **[Download Latest Tagged Release (`a3270.apk`)](https://git.hugfreevikings.wtf/rudi/a3270/releases)**
- **[Latest Nightly CI Artifacts](https://git.hugfreevikings.wtf/rudi/a3270/actions)** (Download under the latest successful workflow run)
### Installing `a3270`
To install the APK on a connected Android device or emulator via `adb`:
```bash
adb install -r a3270.apk
```
---
## ✨ Features
- **Modern Jetpack Compose UI**: Responsive, touch-optimized 3270 terminal screen rendering.
- **TN3270 & TN3270E Protocol Support**: RFC 2355 compliant state machine, negotiation, Device-Type query, and SSL/TLS encryption via `lib3270j`.
- **On-Screen Function Key Bar**: Quick-access touch bar for PF1PF24, PA1PA3, Enter, Clear, Reset, and Attn keys.
- **IND$FILE File Transfer**: Full mobile UI for **CUT** and **DFT (DDM)** high-speed structured field file transfers with ASCII/binary translation, CRLF handling, and recfm/lrecl formatting for TSO, VM/CMS, and CICS.
- **OIA Status Line**: Real-time Operator Information Area displaying connection state, keyboard lock, insert mode, cursor row/col, and LU name.
- **Host Profile Storage**: Save and manage multiple mainframe connection profiles with custom ports, models, and SSL/TLS options.
- **Background Session Persistence**: Android foreground service keeps your terminal session alive when multitasking.
- **Terminal Models**:
- Model 2 (24x80)
- Model 3 (32x80)
- Model 4 (43x80)
- Model 5 (27x132)
---
## 🛠️ Building from Source
### Prerequisites
- **Java Development Kit (JDK)**: JDK 17 or JDK 21 - **Java Development Kit (JDK)**: JDK 17 or JDK 21
- **Android SDK**: Android SDK with API 34 platforms and build-tools installed (`ANDROID_HOME` or `ANDROID_SDK_ROOT` set) - **Android SDK**: API 34 platforms and build-tools (`ANDROID_HOME` or `ANDROID_SDK_ROOT` set)
## Setup & Building
### 1. Clone Repositories Side-by-Side ### 1. Clone Repositories Side-by-Side
For the easiest setup, clone both `j3270` and `a3270` into the same parent folder: For the easiest setup, clone both `j3270` and `a3270` into the same parent folder:
```bash ```bash
@@ -46,15 +77,12 @@ cd a3270
> ``` > ```
### 2. Build the Debug APK ### 2. Build the Debug APK
Using the helper script:
You can build using the helper script:
```bash ```bash
./build.sh ./build.sh
``` ```
Or directly with Gradle Wrapper: Or using Gradle Wrapper directly:
```bash ```bash
./gradlew assembleDebug ./gradlew assembleDebug
``` ```
@@ -64,25 +92,50 @@ The compiled APK will be generated at:
build/outputs/apk/debug/a3270-debug.apk build/outputs/apk/debug/a3270-debug.apk
``` ```
## Deployment / Installation ---
To install the debug APK onto a connected Android device or emulator via `adb`: ## 🏷️ How to Tag & Publish (Beta) Releases
Releases can be published automatically to Gitea via Git tags:
```bash ```bash
adb install -r build/outputs/apk/debug/a3270-debug.apk # 1. Create a version tag (stable or beta)
git tag -a v0.1.0-beta.1 -m "Release v0.1.0-beta.1"
# Or a stable release:
git tag -a v0.1.0 -m "Release v0.1.0"
# 2. Push the tag to Gitea
git push origin v0.1.0-beta.1
``` ```
## Contributing Pushing any `v*` tag triggers the automated release workflow (`.gitea/workflows/release.yaml`), which:
1. Automatically detects pre-releases (tags containing `beta`, `alpha`, `rc`, `pre`, `preview`, or `dev`) and marks them as **Pre-release** on Gitea.
2. Builds the APK and packages it.
3. Publishes a new Gitea Release with `a3270.apk` attached automatically.
Contributions are welcome! ---
## 🔍 Topics & Discoverability
Suggested keywords/topics for repository indexing:
`tn3270` · `tn3270e` · `ibm-3270` · `mainframe` · `terminal-emulator` · `android` · `android-app` · `jetpack-compose` · `kotlin` · `x3270` · `j3270` · `ind-file` · `file-transfer` · `ebcdic` · `z-vm` · `z-os` · `cms` · `tso` · `cics`
---
## 🤝 Contributing
Contributions are welcome! Please feel free to open a bug report or feature request via the Gitea issue tracker.
I have contributed no code to this project, it was entirely written by LLMs with my guidance only. I have contributed no code to this project, it was entirely written by LLMs with my guidance only.
## Acknowledgements ---
- [j3270](https://git.hugfreevikings.wtf/rudi/j3270) ## 📜 Acknowledgements
- [x3270](https://x3270.miraheze.org/wiki/Main_Page)
- [j3270](https://git.hugfreevikings.wtf/rudi/j3270) — Desktop emulator and `lib3270j` protocol engine
- [x3270](https://x3270.miraheze.org/wiki/Main_Page) — Reference C implementation and protocol specifications
- [Antigravity](https://antigravity.google) - [Antigravity](https://antigravity.google)
- Claude Opus 4.6 - Claude Opus 4.6
- Gemini 3.1 Pro (High) - Gemini 3.1 Pro
- Gemini 3.7 Flash (High) - Gemini 3.7 Flash